yannbriancon / spring-hibernate-query-utils Goto Github PK
View Code? Open in Web Editor NEWLibrary giving tools to detect N+1 queries and count the queries generated with Spring and Hibernate
License: MIT License
Library giving tools to detect N+1 queries and count the queries generated with Spring and Hibernate
License: MIT License
Upon updating to Spring Boot 3, I noticed that I'm no longer able to autowire in an instance of HibernateQueryInterceptor
@Autowired private HibernateQueryInterceptor hibernateQueryInterceptor;
Would you be open to a PR that adds a src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
file indicating that com.yannbriancon.config.HibernatePropertiesConfig
should be auto-imported?
The test cases fail in the new package as when User is fetched Eagerly as opposed to Lazy then the message is empty and because of that, the test case fails.
The root cause is when lazy fetched -
stackTraceElement.getClassName().indexOf(entityName) == 0 is true
but when eager fetched it is false.
The old package detects this eager N+1 queries as it didn't had this function
Is there any possibility of working for eclipseLink
Hey,
This lib looks great, I wanted to try it in my Spring Boot app (https://github.com/Athou/lapinstance) but I get a NullPointerException:
Caused by: java.lang.NullPointerException: null
at com.yannbriancon.interceptor.HibernateQueryInterceptor.getEntity(HibernateQueryInterceptor.java:86) ~[spring-hibernate-query-utils-1.0.0.jar:1.0.0]
at org.hibernate.internal.SessionImpl.getEntityUsingInterceptor(SessionImpl.java:550) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.loader.Loader.getRow(Loader.java:1601) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:745) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.loader.Loader.processResultSet(Loader.java:1008) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.loader.Loader.doQuery(Loader.java:964) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2815) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2797) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2629) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
at org.hibernate.loader.Loader.list(Loader.java:2624) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
...
Any idea ?
Thanks !
Are such releases planned?
Reference: CVE-2018-1270 | CVSS Score: 9.8 | Category: CWE-94 | Spring Framework, versions 5.0 prior to 5.0.5 and versions 4.3 prior to 4.3.15 and older unsupported versions, allow applications to expose STOMP over WebSocket endpoints with a simple, in-memory STOMP broker through the spring-messaging module. A malicious user (or attacker) can craft a message to the broker that can lead to a remote code execution attack.
As it is public repository. Please include sonarcloud.
False postive EAGER queries are being reported when more than one proxy is in the application stack. For example, a Spring RMI layer in front of the Spring Data Repository call. The RMI layer would be the top-most proxy and be detected first, resulting in isolated/unrelated query methods being considered for eager fetches. The code here increments based on the proxy name, which is detected incorrectly. This seems to stem from the code in getProxyMethodName()
Why did you choose to walk the stack backward (top-down), vs starting at the bottom and going up? If it were reversed, wouldn't it find the more accurate proxy method or would that lead to missed detections?
This is possibly related to #26, but not isolated to testing.
Consider improving the proxy detection by doing one of the following:
The property hibernate.query.interceptor.error-level
is not working anymore since 2.0.0 release in application.properties.
Instead spring-hibernate-query-utils.n-plus-one-queries-detection.error-level
need to be used.
would be nice if the query counter could be configured to filter only specific types of sql statements, like INSERT or UPDATE or SELECT.
Hey, thanks for this awesome project, as far as I can see the latest version is 2.0 but it's not in maven central. I need new version in order to be able to disable query-utils for specific profiles (enable property is not present in latest release 1.3). Could you upload a new version please . Cheers
For tests with @DataJpaTest HibernateQueryInterceptor is not registered automatically.
I can not load it somehow cause it is package visible only. Also I tried to add spring.jpa.properties.hibernate.session_factory.interceptor=com.yannbriancon.interceptor.HibernateQueryInterceptor, but without effect. The possible workaround is to copy-paste HibernatePropertiesConfig and add @import({HibernateQueryInterceptor.class, HibernatePropertiesConfig.class}) to test class
I have following Repository:
public interface ObjectRepository extends JpaRepository<ObjectEntity, Long>,
JpaSpecificationExecutor<ObjectEntity> {
@Query("select distinct so from ObjectEntity so join fetch so.objectAssignmentCounts where so.customerId= :customerId and so.id IN (:ids)")
List<ObjectEntity> getObjectsById(@Param("customerId") Long customerId, @Param("ids") List<Long> ids, Sort sort);
}
In my test code I call my API several times which will call the ObjectRepository.getObjectsById with different paramerts and sorting.
I see that sometimes the testcase fails if running multiple tests in sequence.
It seems that the proxy method for the getObjectById is then the same but only the sorting is different.
Eg.: proxyMethodName= com.sun.proxy.$Proxy195getObjectsById
initial query:
select distinct ... order by obje0_.created_at asc
new query:
select distinct ... order by obje0_.name asc
This is then causing to increment the select queries count and report an error:
com/yannbriancon/interceptor/HibernateQueryInterceptor.java:212
selectQueriesInfoPerProxyMethod.put(proxyMethodName, selectQueriesInfo.incrementSelectQueriesCount());
2021-05-12 21:28:11.635 ERROR 4168c0df-cbe7-47d7-aa89-18ec834b214f GlobalExceptionHandler:332 - N+1 queries detected with eager fetching on the entity com.test.jpa.model.ObjectEntity
at com.test.service.QueryService.getObjects(QueryService.java:148)
Hint: Missing Lazy fetching configuration on a field of type com.test.jpa.model.ObjectEntity of one of the entities fetched in the query
I can't reproduce it if I debug a single test or try to stop the debugger on this testcase.
I need to set a breakpoint on com/yannbriancon/interceptor/HibernateQueryInterceptor.java:212
while running tests in sequence.
I think it's a mix of a threading/testcase-seperation issue together with the sorting of spring data so that same proxy method is used.
Java 16+ broke the N+1 query detection, it seems that the proxy's package has changed.
I've tested locally and setting the value of PROXY_METHOD_PREFIX to jdk.proxy2
instead of com.sun.proxy
in those versions does the trick.
I would happily submit a PR that checks the Java runtime version and set the PROXY_METHOD_PREFIX
accordingly if that's an acceptable solution.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.