-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Query validation significantly slows down application startup [DATAJPA-1370] #1690
Comments
Oliver Drotbohm commented Care to add some numbers to back "significantly slows down"? We have quite some extensive benchmarks in Spring Boot that indicate that Spring Data JPA only adds negligible bootstrap overhead compared e.g. to the native Hibernate bootstrap time. I'll use this ticket to make sure we avoid the |
Сергей Цыпанов commented Sure, currently my metrics are approximate, right now I try to create sime reliable benchmark. We have a project with Spring Data JPA under Spring Boot. Once someone add a dependency spring-boot-starter-data-ldap into a list of dependencies and we immediately spotted an increase in startup time. Debugging demonstrated that when Spring Boot initialized its context all repositories extending JpaRepository we treated as both JPA and LDAP repositories and query validation occurred. I've excluded spring-boot-starter-data-ldap from dependencies and turned off ldap repositories by adding spring.ldap.repositories.enabled: false into application.yml. Startup time reduction was about 15 seconds, I think this is the time wasted onto queries validation for ldap repos. Validation for JPA repos should cost us the same. I understand this metrics is quite naive, but currently it's all I have |
Сергей Цыпанов commented P.S. On your project we have 93 repository interfaces extending JpaRepository and 118 |
Oliver Drotbohm commented Thanks, Сергей Цыпанов. That's very helpful information. What puzzles me a bit is that having two Spring Data modules on the classpath actually triggers a strict repository scanning mode which assigns a repository to a store by inspecting it closer (the repository base interface, annotations on the entity class managed etc.). I.e. it's kind of impossible that an interface is "assigned" to both stores, mostly because both store implementations would end up using the same bean name for the bean definitions registered and thus only one end up surviving as one would override the other. I just checked Spring Data LDAP and it seems to have all things in place to take part in this more strict mode (ultimately it's these two methods in We have an example for using both MongoDB and JPA in our examples repository. You should be able to produce similar output in you case. Does that help diagnosing the issue? |
Сергей Цыпанов commented Oliver Drotbohm
Getting back to you last comment:
Those messages count is the same as number of interfaces inheriting JpaRepository, but unlike the multi-store example you provided log messages are coming only for LDAP, not for both LDAP and JPA, so the behaviour is slightly different. I cannot attach sources of the project, but I'll try to build one for demonstration having exactly the same dependencies and configuration. |
Сергей Цыпанов commented Not sure, but it seems I've got high-level understanding of what happened. In multi-store example both TreasureRepository and PersonRepository extend CrudRepository i.e. top-level interface in inheritance hierarchy. This is why both spring-boot-starter-data-mongodb and spring-boot-starter-data-jpa pick them up. But in my case all our repositories extend JpaRepository and should be picket only by spring-boot-starter-data-jpa, not spring-boot-starter-data-ldap. What happens instead is that spring-boot-starter-data-ldap finds interfaces extending JpaRepository and tries to process them. As for me this is wrong and must be changed, as a child of JpaRepository by its nature is bound to JPA, not LDAP. P.S. Demonstration example fails to start when TreasureRepository's parent is changed from CrudRepository to JpaRepository:
|
andrew-landsverk-win commented I am also seeing weirdness with both data-cassandra and data-jpa on the classpath. I am strictly using JpaRepository and CassandraRepository as my base classes, yet spring-data-cassandra is insisting on checking the JpaRepository repositories and asking me to use cassandra specific interfaces even though these repositories are for Spring Data JPA. The application starts and loads fine, but these info messages are incorrect and misleading in my opinion, but maybe it's a setup issue on my end? |
Oliver Drotbohm commented The repository base interface is a quite unfortunate differentiator for the stores as we effectively cannot teach LDAP about all potential other Spring Data stores to ignore. To it, the repository is extending a Spring Data interface (as In single store mode it will just use it straight away. In strict mode, i.e. if multiple stores are on the classpath, the repository should only be processed completely if it either implements the store specific repository or the domain type managed by the repository is annotated with a store specific annotation, I guess it makes sense to add that if you see the message that a repository has been dropped by a particular store, no inspection of the repository or queries defined in it has been performed yet. That message is the result of a pure assignability / annotation presence check (again see Сергей Цыпанов – I cannot follow your statements. The example linked to does not contain the mentioned repositories.
This is exactly what's expected if all your repositories are JPA repositories. LDAP would have to have a look at the JPA ones and signal that it's not gonna process them. JPA doesn't have to issue these logs as it's not dropping the repositories but actually taking them forward to eventually become Spring Beans. If anyone of you can provide a minimal, reproducing project, that'd be helpful. Or modify one of the Spring Data examples projects to show the problem |
Is there any update on this work? Thanks, |
Сергей Цыпанов opened DATAJPA-1370 and commented
Having dozens of interfaces extending JpaRepository and several hundreds of methods annotated with
@Query
it takes application significant type to start up.I think there could be an option to disable validation e.g. for tests.
Also SimpleJpaQuery::validateQuery can be improved: e.g. we should compute error message only if necessary
2 votes, 4 watchers
The text was updated successfully, but these errors were encountered: