spring-projects / spring-data-mongodb

Provides support to increase developer productivity in Java when using MongoDB. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
https://spring.io/projects/spring-data-mongodb/
Apache License 2.0
1.61k stars 1.08k forks source link

Target bean of type java.lang.Integer is not of type of the persistent entity [DATAMONGO-2149] #3018

Closed spring-projects-issues closed 5 years ago

spring-projects-issues commented 5 years ago

eacdy opened DATAMONGO-2149 and commented

I have two entities: user and company.

The relation between them are many to many.Which means one user belongs to many companies and one company may have lots of user.

Now, I want to query a user with his companies. In case this guy's companies are too many, I want to show only 5 companies in one page.

Code is like below:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Document
public class User {
  @Id
  private String id;

  private String username;

  private String password;

  @DBRef
  private List<Company> companies;
}

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Document
// 如果不指定,那就是包名全路径
@TypeAlias("company")
public class Company {
  @Id
  private String id;
  private String name;
}

@GetMapping("/users/{id}")
public Mono<User> findById(@PathVariable String id) {
  User byCompanyId = this.userRepository.find(id, 0, 1);
  return Mono.just(byCompanyId);
}

@Repository
public interface UserRepository extends CrudRepository<User, String> {
  @Query(value = "{ 'id' : ?0}", fields = "{ 'companies': { '$slice': [?1,?2] } }")
  User find(String id, int skip, int limit);
}

WHEN I CALL endpoint /users/{id}

I Can only receive ERROR like below:

java.lang.IllegalArgumentException: Target bean of type java.lang.Integer is not of type of the persistent entity (com.itmuch.odin.entity.test.Company)!java.lang.IllegalArgumentException: Target bean of type java.lang.Integer is not of type of the persistent entity (com.itmuch.odin.entity.test.Company)! at org.springframework.util.Assert.isTrue(Assert.java:134) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE] at org.springframework.data.mapping.model.BasicPersistentEntity.getPropertyAccessor(BasicPersistentEntity.java:431) ~[spring-data-commons-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.createDBRef(MappingMongoConverter.java:936) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.toDBRef(MappingMongoConverter.java:382) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.core.convert.QueryMapper.createDbRefFor(QueryMapper.java:538) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.core.convert.QueryMapper.convertAssociation(QueryMapper.java:471) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.core.convert.QueryMapper.convertAssociation(QueryMapper.java:445) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedKeyword(QueryMapper.java:290) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedObjectForField(QueryMapper.java:229) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedObject(QueryMapper.java:140) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedFields(QueryMapper.java:191) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.core.MongoTemplate.getMappedFieldsObject(MongoTemplate.java:2569) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:2274) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.core.ExecutableFindOperationSupport$ExecutableFindSupport.doFind(ExecutableFindOperationSupport.java:213) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.core.ExecutableFindOperationSupport$ExecutableFindSupport.oneValue(ExecutableFindOperationSupport.java:138) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.repository.query.AbstractMongoQuery.lambda$getExecution$4(AbstractMongoQuery.java:124) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.mongodb.repository.query.AbstractMongoQuery.execute(AbstractMongoQuery.java:97) ~[spring-data-mongodb-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:602) ~[spring-data-commons-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:590) ~[spring-data-commons-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE] at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) ~[spring-data-commons-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE] at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE] at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61) ~[spring-data-commons-2.0.11.RELEASE.jar:2.0.11.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE] at com.sun.proxy.$Proxy83.find(Unknown Source) ~[na:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:197) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.0.10.RELEASE.jar:5.0.10.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE] at com.sun.proxy.$Proxy83.find(Unknown Source) ~[na:na] at com.itmuch.odin.controller.UserController.findByCompanyId(UserController.java:56) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181] at org.springframework.web.reactive.result.method.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:243) ~[spring-webflux-5.0.10.RELEASE.jar:5.0.10.RELEASE] at org.springframework.web.reactive.result.method.InvocableHandlerMethod.lambda$invoke$0(InvocableHandlerMethod.java:138) ~[spring-webflux-5.0.10.RELEASE.jar:5.0.10.RELEASE] at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:118) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1083) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.MonoZip$ZipCoordinator.signal(MonoZip.java:247) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.MonoZip$ZipInner.onNext(MonoZip.java:329) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:185) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onNext(FluxDefaultIfEmpty.java:92) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:1640) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:1454) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:1328) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:161) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:53) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.MonoSwitchIfEmpty.subscribe(MonoSwitchIfEmpty.java:44) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.MonoDefaultIfEmpty.subscribe(MonoDefaultIfEmpty.java:37) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.MonoPeek.subscribe(MonoPeek.java:71) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.Mono.subscribe(Mono.java:3088) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.MonoZip.subscribe(MonoZip.java:128) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:153) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.MonoPeekFuseable.subscribe(MonoPeekFuseable.java:74) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE] at reactor.core.publisher.MonoPeekFuseable.subscribe(MonoPeekFuseable.java:74) ~[reactor-core-3.1.10.RELEASE.jar:3.1.10.RELEASE]

 

But When I use mongo client I got the result I want. 

!image-2018-11-28-16-47-34-817.png!

SO I wonder Whether this is a bug, Or I used it in a wrong way.

 

Here goes the code:

[^odin.zip]


Affects: 2.0.12 (Kay SR12), 2.1.3 (Lovelace SR3)

Attachments:

Issue Links:

Referenced from: pull request https://github.com/spring-projects/spring-data-mongodb/pull/623

Backported to: 2.1.4 (Lovelace SR4), 2.0.13 (Kay SR13), 1.10.18 (Ingalls SR18)

spring-projects-issues commented 5 years ago

Oliver Drotbohm commented

It looks like we#re not properly processing the $slice keyword for DbRefs. In fact, I don't even think we support parameter bindings into a fields spec yet. AFAIR it's only passed throught the QueryMapper to make sure we map the fields names properly

spring-projects-issues commented 5 years ago

eacdy commented

Oliver Drotbohm Thanks a lot. I think I am gonna give up using DBRef