9

I'm using Spring Data Mongodb library and I don't know to find by @Query an element in two collections joined with @DBRef, like this:

User:

@Document
public class User {

@Id
@JsonSerialize(using=ObjectIdSerializer.class)
private ObjectId id;

@CreatedDate
private Date dateCreated = new Date();

@LastModifiedDate
private Date dateModified = new Date();

@NotEmpty
@Indexed
private String name;

@Language
private String lang;

@NotEmpty
@DBRef
private Club club;
...

Club:

@Document
public class Club {

@Id
@JsonSerialize(using=ObjectIdSerializer.class)
private ObjectId id;

@Indexed(unique = true)
private String name;

private Address address;
...

UserRepository:

@Query("{\"$or\":"
            + "["
                + "{\"name\" : {\"$regex\" : ?0, \"$options\": \"i\"}}, "
                + "{\"club.name\" : {\"$regex\" : ?0, \"$options\": \"i\"}} "
            + "]"
        + "}")
public Page<User> findAll(String query, Pageable pageable);

error:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.data.mapping.model.MappingException: Invalid path reference club.name! Associations can only be pointed to directly or via their id property! at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:980) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859) at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844) at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167) at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134) at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:155) at it.stasbranger.rotarylive.controller.UserControllerTests.showUsersFilterTEST3(UserControllerTests.java:137) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at com.lordofthejars.nosqlunit.core.AbstractNoSqlTestRule$1.evaluate(AbstractNoSqlTestRule.java:72) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48) at org.junit.rules.RunRules.evaluate(RunRules.java:20) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) Caused by: org.springframework.data.mapping.model.MappingException: Invalid path reference club.name! Associations can only be pointed to directly or via their id property! at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.getPath(QueryMapper.java:853) at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.(QueryMapper.java:729) at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.(QueryMapper.java:706) at org.springframework.data.mongodb.core.convert.QueryMapper.createPropertyField(QueryMapper.java:216) at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedObject(QueryMapper.java:122) at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedKeyword(QueryMapper.java:235) at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedObject(QueryMapper.java:100) at org.springframework.data.mongodb.core.MongoTemplate.count(MongoTemplate.java:724) at org.springframework.data.mongodb.repository.query.AbstractMongoQuery$PagedExecution.execute(AbstractMongoQuery.java:268) at org.springframework.data.mongodb.repository.query.AbstractMongoQuery.execute(AbstractMongoQuery.java:106) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:462) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:440) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) at com.sun.proxy.$Proxy132.findAll(Unknown Source) at it.stasbranger.rotarylive.service.UserServiceImpl.findAll(UserServiceImpl.java:71) at it.stasbranger.rotarylive.controller.UserController.showUsers(UserController.java:53) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968) ... 42 more

Flavio Troia
  • 2,451
  • 1
  • 25
  • 27

3 Answers3

0

It is not possible to query on DBRef in MongoDB itself. Thus it is not possible to do so using Spring Data MongoDB. The resulting error is very clear about that in its message "Associations can only be pointed to directly or via their id property!"

Christoph Strobl
  • 6,491
  • 25
  • 33
0

As the error message implies, in the query, it will only allow using the id of the referenced document.

thilinaj
  • 369
  • 3
  • 6
0

Others already answered why this error happens. If you must have this I suppose there are two ways to go about it.

  1. query clubDB first and get ID of matching names. Have user select on the options and use those selected IDs to search userDB. Sort of like you have to select an option in a drop-down like state selection.

  2. query clubDB and get a list of all IDs of matching names and query userDB for all these IDs. With this option, user probably won't have to change how they interact with the application.

Roijjer
  • 57
  • 7