Does Spring Data 2.0 change nullability rules about sorting and paging? - spring

I'm making migration from spring-boot 1.5.6 to 2.1.7 and facing so many issues.
When I see discussion about migration, looks simple but not for me. I got 2 very big issues :
I implement a filter to make a process of uncrypt uri and to call filter once again with request dispatcher. In 1.5.6 the code is ok, the request goes into doFilter, be uncrypt, httpRequest.getDispatcher.forward and call a second time doFilter which finally call chain.doFilter.
Now in spring-boot 2.1.7 requestDispatcher's forward didn't reach a second time doFilter... Never found a doc on it.
Basic calls like /api/users (which means a findAll) worked on 1.5.6 but fail with NPE in 2.1.7 cause of sorting. I can't call a findAll like /api/users or /api/users/7/books I always get an error :
java.lang.NullPointerException at
org.springframework.data.jpa.repository.support.Querydsl.applySorting(Querydsl.java:128)
Did someone get explanation for that ?

Yes. Both Sort and Pageable now expose dedicated null-objects via Sort.unsorted() and Pageable.unpaged() to express the absence of sorting or pagination information in particular.
You should already see an IDE warning if you enable the annotation based verification of null values. That said, I just rechecked the Javadoc and referencedocs and think we can do better here. I've filed the following tickets:
DATACMNS-1568 (fixed) - General documentation updates about nullability in the repository reference docs.
DATACMNS-1569 (fixed) - Nullability constraints in Querydsl APIs.
DATAJPA-1594 (fixed) - Tighten nullability constraints in Spring Data JPAs Querydsl integration.

Related

springfox implementation available for swagger3 or openapi 3?

Is there any springfox implementation available for swagger3 or OpenAPI 3 which support media-type versioning of the endpoint, apart from JAX-RS?
Short answer: no. See 2023 update at end.
There is a pinned issue tracking this in springfox's github: https://github.com/springfox/springfox/issues/3070
Best read that for the latest news, but at the moment the project is lagging both OpenAPI and Spring Boot, and the list of changes needed is quite long. The project owner sounds a bit overwhelmed and has asked for help from the community.
Based on that, I'd say the future of springfox is in doubt. Hopefully this will pass. But given the difficulties they are having it might be worth looking for alternatives.
One is: https://github.com/springdoc/springdoc-openapi
While it certainly doesn't have the documentation, community and stockpile of answered questions that springfox has, the basic functionality works. I've only just started using it so that's all I can say at the moment. :-)
2023 Update: The answer is "no" again. Springfox 3.0 worked again for a while but doesn't seem to be supported for Spring Boot 2.5 or higher. We have now migrated to springdoc-openapi and found that it wasn't difficult to do. See: https://springdoc.org/migrating-from-springfox.html
One small gotcha is you may need to review all places you use #Parameter on a #RequestParam. If the parameter type is a class with multiple fields, you sometimes need to use #ParameterObject instead of #Parameter. That tells Springdoc to document each member of the class as a separate request parameter.

OptaPlanner got java reflection error in Spring boot

I just tried to run an OptaPlanner project in Spring Boot, but there's only very simple text in OptaPlanner User Guide for Spring.
Actually, I think it is very easy to copy all domain objects, configuration files and drools files from an OptaPlanner project to Spring Boot project without any changes, but the only question is how to call Solver's solve method.
I made it run after Spring Boot startup with a class (named CommandLineAppStartupRunner) which implements CommandLineRunner interface, and I called solve method in its run method. Finally, I got an exception like follows:
Caused by: java.lang.IllegalArgumentException: Can not set org.optaplanner.core.api.score.buildin.hardmediumsoft.HardMediumSoftScore field springbootcloudbalance.domain.CloudBalance.score to springbootcloudbalance.domain.CloudBalance
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
at java.lang.reflect.Field.get(Field.java:393)
at org.optaplanner.core.impl.domain.common.accessor.ReflectionFieldMemberAccessor.executeGetter(ReflectionFieldMemberAccessor.java:54)
at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.getScore(SolutionDescriptor.java:1071)
at org.optaplanner.core.impl.score.director.AbstractScoreDirector.cloneSolution(AbstractScoreDirector.java:212)
at org.optaplanner.core.impl.solver.scope.DefaultSolverScope.setWorkingSolutionFromBestSolution(DefaultSolverScope.java:230)
at org.optaplanner.core.impl.solver.AbstractSolver.solvingStarted(AbstractSolver.java:75)
at org.optaplanner.core.impl.solver.DefaultSolver.solvingStarted(DefaultSolver.java:210)
at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:190)
at springbootcloudbalance.CommandLineAppStartupRunner.run(CommandLineAppStartupRunner.java:55)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:818)
... 10 common frames omitted
I checked the code, and found the exception throws because the object from field.getDeclaringClass() is a different instance from the one from var1.getClass(). I'm afraid it due to the implementation of java reflection conflicts between OptaPlanner and Spring Boot.
The version I used is as follows:
OptaPlanner 7.11.0.Final
Spring Boot 2.0.5.RELEASE
JVM 1.8.0_181
Removing the spring-boot-devtools dependency fixes this error. Another SO question similar to this one explains it has something to do with different classloaders: Optaplanner's Drools working memory is empty. The accepted answer also mentions a possible fix:
To fix it, configure spring dev tools to load Drools libraries in the RestartClassLoader, together with the project's classes: using-boot-devtools-customizing-classload
Nick's answer is correct. This is just to figure out what's going on.
This line means that optaplanner is extracting CloudBalance.getScore():
at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.getScore(SolutionDescriptor.java:1071)
This line means that it's using a ReflectionFieldMemberAccessor for that, which is just way to read a field through reflection (including private fields):
at org.optaplanner.core.impl.domain.common.accessor.ReflectionFieldMemberAccessor.executeGetter(ReflectionFieldMemberAccessor.java:54)
Now the error message is where it gets interesting:
Can not set ...HardMediumSoftScore field ...CloudBalance.score to ...CloudBalance
It looks like basically doing:
CloudBalance cloudBalance2 = cloudBalance.getScore();
Huh?
Musa provided this answer, but someone deleted it, despite that the JIRA link is extremely relevant, as it points out which version of OptaPlanner will deal better with this problem:
"An issue was submitted to OptaPlanner to provide better error messages for such cases: https://issues.jboss.org/browse/PLANNER-1586. Feel free to add any comments or suggestions."

Update specific field in mongodb of a spring-boot app using spring-data feature

Can we update only specific field in mongodb of a spring-boot app using spring-data feature?
Currently, spring-data provides a save method to update as well as save in a document. If two sets of concurrent updates happen in a single document for the different field, we can lose information. I know we can solve the problem using Mongotemplate. Can we solve these problems using spring-data?
Thanks
What about Optimistic Locking feature?
The #Version annotation provides syntax similar to that of JPA in the context of MongoDB and makes sure updates are only applied to documents with a matching version. Therefore, the actual value of the version property is added to the update query in such a way that the update does not have any effect if another operation altered the document in the meantime. In that case, an OptimisticLockingFailureException is thrown.
See Spring Documentation: https://docs.spring.io/spring-data/mongodb/docs/2.0.9.RELEASE/reference/html/#mongo-template.optimistic-locking
With MongoDB 4.0, ACID transactions have arrived in the Document store, enforcing all-or-nothing execution and maintaining data integrity. So, let’s get straight to it by looking at both the synchronous and the reactive execution models.
you could write code like this:
#Transactional
void insertDocuments() {
operations.insert(documentOne);
operations.insert(documentTwo);
}
Complete Spring's documentation:
https://spring.io/blog/2018/06/28/hands-on-mongodb-4-0-transactions-with-spring-data

Grizzly and Jersey are hiding my other annotations

we have to update a Spring project where we need to embed a https server which supports SSL protocols and cipher suites selection.
My setup is : Spring 3.2.4, jersey 1.15.1 and Grizzly 1.9.60
The main problem that our resource class is calling some components which are expecting annotations. But Grizzly seems to ignore the non-jersey REST annotations. So my custom annotations aren't transmitted at all.
I was wondering if you can give a an idea on how to work past this:
is it possible to configure Jersey so it won't use annotations (maybe a xml or java config), hopefully keeping my own annotations to be transmitted down the line ?
or it is possible to manually add the annotations on the method call ?
I recently tried this with Jetty 1.9.2 and jersey2 and it seems I have the same result. The only thing that worked was a SimpleServerFactory from Jersey 1, but like I said it didn't provide customizable SSL parameters.
Please someone :) ...
OK, just posting here maybe it will help someone. I finally got my hands on the components code and I noticed that the called class was looking for annotations in the last three stack traces.
What happened was Grizzly was adding a proxy of some kind, and that causes the three stack traces not to be enough and the annotations were not sent through.

Is there a complete reference / documentation of Spring annotations?

For instance, if I open the Spring Framework Reference Documentation and open 5.9.2. #Autowired, I get this explanation: As expected, you can apply the #Autowired annotation to "traditional" setter methods:.
Not very informative. Actually, the explanation assumes prior knowledge given that I'm expected to have certain expectations.
So is there complete reference of annotations somewhere?
DZone had a refcard about Spring Annotations a good while back so its not the most up to date but this might still be useful to you - http://refcardz.dzone.com/refcardz/spring-annotations
You will need to quickly create an account if you dont have one (free by the way) but its worth it for all the other refcards anyway.
I think the official spring documentation is very good but ya you cant just jump into a section like 5.2.9 without prior knowledge of the how the dependency injection framework works etc.
And btw, the refcard was written by Craig Walls who is the author of the Spring in Action book series so you can be confident that the document is correct (albeit dated).

Resources