0
votes

I'm trying to find results in my mongodb database with querydsl and spring-data, I get some results when I use a MyInterfaceImpl type in the class MyDocument. If I use MyInterface, I get no results. Using MongoRepository, I also get results with MyInterface. Is there something particular with QueryDSL and interfaces in Java? Have I missed something?

I found the following post, but still get the same results with or without @QuerySupertype on MyInterface:

How queryDSL works with interface?

package com.myapp.bean.subfolder;

...

@Document
public class MyDocument implements Comparable<MyDocument>, IMyDocument{

   private MyInterface myInterface;

   @Id
   private String id;

   @CreatedDate
   private Date createdDate;

   public void setCreatedDate(Date createdDate) {
     this.createdDate = createdDate;
   }

   public Date getCreatedDate() {
      return createdDate;
   }

   public void setMyInterface(MyInterface myInterface) {
      this.myInterface = myInterface;
   }

   public MyInterface getMyInterface() {
      return myInterface;
   }

   ...
}

MyInterface:

package com.myapp.bean;

@QuerySupertype
public interface MyInterface {

   public MyInterfaceImplBase getMyInterfaceImplBase();
   public void setMyInterfaceImplBase(MyInterfaceImplBase myInterfaceImplBase);
   public String getIdExterne();
   public void setIdExterne(String idExterne);
}

MyInterfaceImpl:

package com.myapp.bean.subfolder;

...

@Document
public class MyInterfaceImpl implements MyInterface{
   private MyInterfaceImplBase myInterfaceImplBase;
   @Id
   private String idExterne;

   public MyInterfaceImplBase getMyInterfaceImplBase() {
      return myInterfaceImplBase;
   }

   public void setMyInterfaceImplBase(MyInterfaceImplBase myInterfaceImplBase) {
      this.myInterfaceImplBase = myInterfaceImplBase;
   }

   public String getIdExterne() {
      return idExterne;
   }

   public void setIdExterne(String idExterne) {
      this.idExterne = idExterne;
   }
}

MyInterfaceImplBase.java:

package com.myapp.bean;

...

@Document
public class MyInterfaceImplBase {
   @Id
   private String internalId;

   public String getInternalId() {
      return internalId;
   }

   public void setInternalId(String internalId) {
      this.internalId = internalId;
   }
}

MyDocumentRepository.java:

package com.myapp.repository;

...

public interface MyDocumentRepository extends MongoRepository<MyDocument, String>, QueryDslPredicateExecutor<MyDocument> {
   Collection<MyDocument> findByMyInterface(MyInterface myInterface);
}

MyService.java:

package com.myapp.service;

---

@Service
public class MyService {
   @Autowired
   MyDocumentRepository myDocumentRepository; 

   public Iterable<MyDocument> findById(String id){
      BooleanExpression booleanExpression = QMyDocument.myDocument.myInterface.externalId.eq("1");
      return myDocumentRepository.findAll(booleanExpression);
   }

}

MyServiceTest.java:

package com.myapp.service;

...

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={MongoConfig.class, ServiceConfig.class, BeanConfig.class, FactoryConfig.class})
public class MyServiceTest {
   @Autowired
   MyService myService; 

   @Before
   public void setup() {

   }

   @Test
   public void findByObjectIdInDB(){
      String id = 1;
      Iterable<MyDocument> iterableResult = myService.findById(id);
      assertEquals(1,Lists.newArrayList(iterableResult).size());
   }
}

The data in mongodb:

{ "_id" : ObjectId("58b09c55a7986c0ce0407a76"), "_class" : "com.myapp.bean.subfolder.MyDocument", "myInterface" : { "_class" : "com.myapp.bean.subfolder.MyInterfaceImpl", "_id" : "1", "myInterfaceImplBase" : { "_id" : "2" }}, "createdDate" : ISODate("2017-02-24T20:49:25.891Z") }

When I run MyServiceTest.java: booleanExpression = "myDocument.myInterface.idExterne = 1"

Here's the related info from my pom.xml:

<dependency>
   <groupId>org.mongodb</groupId>
   <artifactId>mongo-java-driver</artifactId>
   <version>3.3.0</version>
</dependency>

<dependency>
   <groupId>org.springframework.data</groupId>
   <artifactId>spring-data-mongodb</artifactId>
   <version>1.9.4.RELEASE</version>
</dependency>

 <dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-jpa</artifactId>
    <version>4.1.4</version>
 </dependency>

 <dependency>
     <groupId>com.querydsl</groupId>
     <artifactId>querydsl-core</artifactId>
     <version>4.1.4</version>
 </dependency>

 <dependency>
     <groupId>com.querydsl</groupId>
     <artifactId>querydsl-mongodb</artifactId>
     <version>4.1.4</version>
 </dependency>

<plugin>
   <groupId>com.mysema.maven</groupId>
    <artifactId>apt-maven-plugin</artifactId>
    <version>1.1.3</version>
    <executions>
       <execution>
          <goals>
             <goal>process</goal>
          </goals>
          <configuration>
             <outputDirectory>target/generated-sources/apt</outputDirectory>

           <processor>org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor</processor>
          </configuration>
       </execution>
    </executions>

    <dependencies>
       <dependency>
          <groupId>com.querydsl</groupId>
          <artifactId>querydsl-apt</artifactId>
          <version>4.1.4</version>
       </dependency>
    </dependencies>
 </plugin>
1

1 Answers

0
votes

I found the answer. The problem was in MyService, I can't execute

QMyDocument.myDocument.myInterface.externalId.eq("1");

The interface has to be casted with the as method of EntityPathBase:

QMyDocument.myDocument.myInterface.as(MyInterfaceImpl.class).externalId.eq("1");