'Spring Data MongoDb - how to use "findAll" method which return only valid documents
I use Spring data mongo as ORM for accessing to my MongoDb. I need to read a MongoDb collection containing documents that I don't manage content and its validity. And I'm facing an issue: Documents are not all valid and when I use 'findAll' method, I just catch an exception. Instead of this behaviour, I would like to find all valid documents and reject invalid ones.
For example, I have a bean with a primitive boolean and in the document, this field is set to a String type. So when I use 'findAll' I get an exception for now, but I would like to have the list of all valid documents. What I means is that some document in my collection are invalid due to bad type - cannot be cast in the bean Java type. I just use a boolean example but it can also appear with int, long, all primitive Java type. There is a way to do that with Spring data mongo?
Many thanks,
Here the stack stace:
java.lang.IllegalStateException: Failed to execute CommandLineRunner at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:779) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE] at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE] at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE] at hello.Application.main(Application.java:38) [classes/:na] Caused by: java.lang.NullPointerException: null at hello.Customer_Accessor_sbf1mo.setProperty(Unknown Source) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mapping.model.ConvertingPropertyAccessor.setProperty(ConvertingPropertyAccessor.java:58) ~[spring-data-commons-1.13.3.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter$1.doWithPersistentProperty(MappingMongoConverter.java:290) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter$1.doWithPersistentProperty(MappingMongoConverter.java:278) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:330) ~[spring-data-commons-1.13.3.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:278) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:238) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:198) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:194) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:85) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mongodb.core.MongoTemplate$ReadDbObjectCallback.doWith(MongoTemplate.java:2313) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1966) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1784) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1767) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:641) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:359) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:197) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:51) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_111] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_111] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_111] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_111] at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:504) ~[spring-data-commons-1.13.3.RELEASE.jar:na] at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:489) ~[spring-data-commons-1.13.3.RELEASE.jar:na] at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461) ~[spring-data-commons-1.13.3.RELEASE.jar:na] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.8.RELEASE.jar:4.3.8.RELEASE] at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) ~[spring-data-commons-1.13.3.RELEASE.jar:na] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.8.RELEASE.jar:4.3.8.RELEASE] at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.8.RELEASE.jar:4.3.8.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.8.RELEASE.jar:4.3.8.RELEASE] at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57) ~[spring-data-commons-1.13.3.RELEASE.jar:na] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.8.RELEASE.jar:4.3.8.RELEASE] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.8.RELEASE.jar:4.3.8.RELEASE] at com.sun.proxy.$Proxy43.findAll(Unknown Source) ~[na:na] at hello.Application.run(Application.java:58) [classes/:na] at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE] ... 6 common frames omitted
Solution 1:[1]
You could create a custom query with WHERE
clause that return only valid data.
To do that you have to create a ObjectRepositoryCustom.java
interface in this way:
@Repository
public interface ObjectRepositoryCustom {
//Where "o.field" is the field you have to check to decide if it's valid or not
@Query("SELECT o FROM Object o WHERE o.field = somethingThatValidsIt")
public List<Object> customFindAll();
}
Then you go in your ObjectRepository.java
and add extends ObjectRepositoryCustom
in this way:
//import your custom repository here
@Repository
public interface ObjectRepository extends JpaRepository<Object,Long>, ObjectRepositoryCustom {
}
Note, I used "Object" type because I don't know your class' name.
Then you can call your query method like this.
private final ObjectRepository objectRepository;
List<Object> result = objectRepository.customFindAll();
I hope it helps!
Solution 2:[2]
Thanks for all your messages above.
I find a easy and robust way to do this (reject invalid document when I ask for a findAll query).
An example below with a bean named Customer
.
DBCollection collection = mongoTemplate.getCollection("customer");
DBCursor cursor = collection.find();
while (cursor.hasNext()) {
DBObject obj = cursor.next();
try {
Customer instance = mongoTemplate.getConverter().read(Customer.class, obj);
// We have now the Customer instance
} catch(Exception exception) {
System.err.println("ERROR: Cannot convert to Customer this DBObject " + obj);
}
}
I hope it could help!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Gozus19 |
Solution 2 | pierre taillard |