Mongo Spring JPA giving IndexOutOfBoundsException in findAll() call - mongodb

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:657)
at java.util.ArrayList.get(ArrayList.java:433)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.bulkReadAndConvertDBRefMapIntoTarget(MappingMongoConverter.java:1447)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readMap(MappingMongoConverter.java:1047)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:225)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1408)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1355)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getValueInternal(MappingMongoConverter.java:952)
at org.springframework.data.mongodb.core.convert.DefaultDbRefResolverCallback.resolve(DefaultDbRefResolverCallback.java:61)
at org.springframework.data.mongodb.core.convert.DefaultDbRefResolver.resolveDbRef(DefaultDbRefResolver.java:103)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readAssociation(MappingMongoConverter.java:358)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:319)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:292)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(M
---------------
This is the calling of mongo jpa method
List<LegalDocument> legalDocumentList = legalDocumentRepository.findAll(Pageable.unpaged()).getContent();
-------------------------------------------------------------
This code is showing the Repository
#Repository
public interface LegalDocumentRepository extends MongoRepository<LegalDocument, String> {
#Override
Page<LegalDocument> findAll(Pageable pageable);
}
I was using this findAll() method from a very long. But now it is giving the IndexOutOfBound. Even i have so many methods available into repository. Please help me in fixing this.
Springboot 2.0.5 release and Mongo 4.2 Atlas

MongoRepository extends PagingAndSortingRepository and you don't need to write method in the repository remove it. Just call like this
Page<LegalDocument> legalDocuments = legalDocumentRepository.findAll(Pageable.unpaged());
And you are using Pageable.unpaged() that means you don't need pagination and use getContent() to get list. But you don't need do that, you can directly get list this way.
List<LegalDocument> legalDocumentList = legalDocumentRepository.findAll();

Related

View Single Record in Spring Boot and Mongo

I'm trying to develop a simple crud application using Spring and Mongodb.
When I'm trying to develop view single data function, I get no error.
But it return value as null when I try in Postman.
Could you please help me to find what is the wrong with my code?
Controller
#GetMapping("/patient/{id}")
public Optional<Patients> findTicketById(#PathVariable("id") #NotNull String id){
System.out.println(id);
return patientRepository.findById(id);
}
Repository
#Repository
public interface PatientRepository extends MongoRepository<Patients, Long> {
Optional<Patients> findById(String id);
}
You can use ifPresentOrElse , check for the usages :
Functional style of Java 8's Optional.ifPresent and if-not-Present?

Call not propagating to the service method from Spring Reactive Controller

I am a beginner to the spring webflux. We are currently migrating our application to Spring Webflux. No I have stuck with a problem. The following is my scenario.
The main service class is calling the following service classes for data
StudentService - return Mono<Student>
StaffService - return Mono<Staff>
Here I have a wrapper class StudentWithMentor to store the result from these service classes.
public class StudentWithMentor {
private Student student;
private Staff mentor;
}
Now in controller I am calling the above 2 services and map it into 'StudentWithMentor' in the following way
Mono<StudentWithMentor> studentWithMentorMono = Mono.just(new StudentWithMentor());
return studentWithMentorMono.map(s->{
studentService.getStudentById(id)
.doOnSuccess(s::setStudent)
.doOnSuccess(st->staffService.getStaffByGrade(st.getGrade()));
return s;
});
But when I call this endpoint I am getting the following result in postman
{
"student": null,
"mentor": null
}
Note: I am getting result from the underlying services when I debugg. But the call is returning before it process.
How can I achieve this in a complete non-blocking way.
Appreciates any help.
The easiest way will be to to use a zipWith operator to merge the results into StudentWithMentor object.
See the code below:
Mono<StudentWithMentor> studentWithMentorMono = studentService.getStudentById(id)
.zipWhen(student -> staffService.getStaffByGrade(student.getGrade()), StudentWithMentor::new);

How to inject spring aop advice for MongoDb call?

I am new to Spring Aop, but I have case to implement AOP advice for a mongo db call(monog db update). I am trying in different way but getting 'Point cut not well formed' error or 'warning no match for this type name: arg string [Xlint:invalidAbsoluteTypeName]'(even if I give absolute name of the argument). Anyone can help on this as how to inject advice for mongo db update call?
#Aspect
#Component
public class DBStatsLoggerAspect {
private static final Logger log = LoggerFactory
.getLogger(DBStatsLoggerAspect.class);
private static final Document reqStatsCmdBson = new Document(
"getLastRequestStatistics", 1);
private DbCallback<Document> requestStatsDbCallback = new DbCallback<Document>() {
#Override
public Document doInDB(MongoDatabase db) throws MongoException,
DataAccessException {
return db.runCommand(reqStatsCmdBson);
}
};
#After("execution( public * com.mongodb.client.MongoCollection.*(..)) && args(org.bson.conversions.Bson.filter,..)")
public void requestStatsLoggerAdvice(JoinPoint joinPoint) {
MongoTemplate mongoTemplate = (MongoTemplate) joinPoint.getTarget();
log.info(mongoTemplate.execute(requestStatsDbCallback).toJson());
}
}
Actual db call method where I need to inject advice:(filter, updatePart all are org.bson.conversions.Bson data type) and here 'collection' is com.mongodb.client.MongoCollection.collection
Document result = collection.findOneAndUpdate(filter, updatePart, new FindOneAndUpdateOptions().upsert(false));
I am not a Spring or MongoDB user, just an AOP expert. But from what I see I am wondering:
You are intercepting execution(public * com.mongodb.client.MongoCollection.*(..)), so joinPoint.getTarget() is a MongoCollection type. Why do you think you can cast it to MongoTemplate? That would only work if your MongoCollection happened to be a MongoTemplate subclass. To me this looks like a bug.
Class MongoCollection is not a Spring component but a third-party class. Spring AOP can only intercept Spring component calls by means of creating dynamic proxies for those components and adding aspect interceptors to said proxies. so no matter how correct or incorrect your pointcut, it should never trigger.
What you can do instead is switch from Spring AOP to full-blown AspectJ. The standard way to do this is to activate AspectJ load-time weaving (LTW).

How to query with Pageable with Spring Data and Couchbase

I just try to query with a PageRequest:
Page<MyEntity> entityPage = myRepository.findAll(new PageRequest(1, 20));
and this is my Repository
#Repository
public interface MyRepository extends CouchbasePagingAndSortingRepository<MyEntity, String> {
}
But always get an empty Page object back.
I'm using 2.1.5.RELEASE for spring-data-couchbase. I read in this older question that it wasn't implemented yet - but this was 2015 and in the Spring Data for Couchbase documentation it's described in detail. So I guess it should work by now ...
You are requesting for second page. Pages are zero indexed, thus providing 0 for page will return the first page.
Try this:
Page<MyEntity> entityPage = myRepository.findAll(new PageRequest(0, 20));

Override findAll() Spring Data Gemfire Repo Queries

I have millions of objects populated in GemFire regions. I don't want default findAll() SDR query to be executed to retrieve the millions of objects in one shot. I am trying to figure out if there is a way to override the default findAll query and provide the LIMIT param to restrict the number of objects retrieved from GemFire Regions. Here is an example of what I want to do:
NoRepositoryBean
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
/**
* Returns all instances of the type.
*
* #return all entities
*/
Iterable<T> findAll();
}
public interface MyRepository extends CrudRepository<MyRepoObject, String> {
#Query("SELECT * FROM MyRegion LIMIT $1")
Iterable<CellTower> findAll(#Param("limit") String limit);
}
Currently, I am on Spring Data Gemfire 1.4.0.BUILD-SNAPSHOT and Spring Data REST 2.0.0.BUILD-SNAPSHOT version
This handy getting started guide on Accessing GemFire Data with REST (https://spring.io/guides/gs/accessing-gemfire-data-rest/) was written not long ago and may help with your particular use case.
The following worked for me. Try using an Integer instead of a String as your parameter to findAll
#Query("SELECT * FROM /Customer LIMIT $1")
List<Customer> findAll(#Param("limit") Integer max);