I am trying to query a MongoDB repository using in criteria on a DBRef. I gathered from the documentation - and by trying - that this isn't supported using the method name to query mapping framework. I am now trying to do this using a custom method and implementation, however, this too isn't working.
Domain objects:
Repository:Code:public class Automaker implements Serializable { private static final long serialVersionUID = 1L; private String id; private String name; public Automaker() { super(); } public Automaker(final String name) { super(); this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class Car implements Serializable { private static final long serialVersionUID = 1L; @Id public String id; @Indexed(unique=true) private String model; @DBRef private Automaker automaker; public Car() { } public Car(final Automaker make, final String model) { this.automaker = make; this.model = model; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getModel() { return model; } public void setModel(String model) { this.model = model; } public Automaker getAutomaker() { return automaker; } public void setAutomaker(Automaker automaker) { this.automaker = automaker; } }
Unit tests:Code:@Repository public interface CarRepository extends MongoRepository<Car, String>, CustomCarRepository { public List<Car> findByAutomaker(Automaker make); public List<Car> findByAutomakerIn(Automaker... makers); } public interface CustomCarRepository { public List<Car> findCarsByAutomakers(Automaker... makers); } public final class CarRepositoryImpl implements CustomCarRepository { @Autowired MongoTemplate template; @Override public List<Car> findCarsByAutomakers(Automaker... makers) { Query q = new Query(new Criteria("automaker").in( (Object[]) makers)); return template.find(q, Car.class); } }
Both testFindByAutomakerIn() and testFindCarsByAutomakers() fail. The former throws an exception:Code:@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "/repositories.xml") public final class CarRepositoryTest { @Autowired AutomakerRepository automakerRepository; @Autowired CarRepository carRepository; private Automaker ford; private Automaker honda; private Automaker toyota; @Before public void setUp() throws Exception { ford = automakerRepository.save(new Automaker("Ford")); honda = automakerRepository.save(new Automaker("Honda")); toyota = automakerRepository.save(new Automaker("Toyota")); carRepository.save(new Car(ford, "Explorer")); carRepository.save(new Car(honda, "Accord")); carRepository.save(new Car(honda, "Civic")); carRepository.save(new Car(honda, "Pilot")); carRepository.save(new Car(toyota, "Camry")); carRepository.save(new Car(toyota, "Yaris")); carRepository.save(new Car(toyota, "Highlander")); } @After public void tearDown() throws Exception { carRepository.deleteAll(); automakerRepository.deleteAll(); } @Test public void testFindByAutomaker() { assertEquals(1, carRepository.findByAutomaker(ford).size()); assertEquals(3, carRepository.findByAutomaker(honda).size()); assertEquals(3, carRepository.findByAutomaker(toyota).size()); } @Test public void testFindByAutomakerIn() { assertEquals(4, carRepository.findByAutomakerIn(ford, toyota)); } @Test public void testFindCarsByAutomakers() { assertEquals(4, carRepository.findCarsByAutomakers(ford, honda)); } }
The latter returns an emptry array because the generated query criteria is incorrect. I posted the code, along with a Gradle build script to GitHub.Code:org.springframework.data.mapping.model.MappingException: No id property found on class class [Lnet.rossillo.car.domain.Automaker; at org.springframework.data.mongodb.core.convert.MappingMongoConverter.createDBRef(MappingMongoConverter.java:688) at org.springframework.data.mongodb.core.convert.MappingMongoConverter.toDBRef(MappingMongoConverter.java:281) at org.springframework.data.mongodb.repository.query.ConvertingParameterAccessor$ConvertingIterator.nextConverted(ConvertingParameterAccessor.java:161) at org.springframework.data.mongodb.repository.query.MongoQueryCreator.nextAsArray(MongoQueryCreator.java:266) at org.springframework.data.mongodb.repository.query.MongoQueryCreator.from(MongoQueryCreator.java:200) at org.springframework.data.mongodb.repository.query.MongoQueryCreator.create(MongoQueryCreator.java:102) at org.springframework.data.mongodb.repository.query.MongoQueryCreator.create(MongoQueryCreator.java:47) at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:109) at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:88) at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:73) at org.springframework.data.mongodb.repository.query.PartTreeMongoQuery.createQuery(PartTreeMongoQuery.java:69) at org.springframework.data.mongodb.repository.query.AbstractMongoQuery.execute(AbstractMongoQuery.java:77) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:313) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) at $Proxy25.findByAutomakerIn(Unknown Source) at net.rossillo.car.repository.CarRepositoryTest.testFindByAutomakerIn(CarRepositoryTest.java:62)
Has anyone found a work around or is there a solution to this?
Thanks in advance,
Scott


Reply With Quote
