All work
- Important performance degration on flush in Hibernate 6HHH-19394
- SQL Interval type is not recognised as comparableHHH-19035Resolved issue: HHH-19035Gavin King
- Informix timestamp literal errorHHH-18531Resolved issue: HHH-18531Vladimír Kuruc
- Cannot define a @Filter condition on two columns on a JOINHHH-18355
- Informix nulls precedence supportHHH-18246Resolved issue: HHH-18246Vladimír Kuruc
- Informix SelectItemReferenceStrategy errorHHH-18244Resolved issue: HHH-18244Vladimír Kuruc
- Informix syntax error in DISTINCT clause before SKIP clauseHHH-18225Resolved issue: HHH-18225Vladimír Kuruc
- Informix plural attribute size function supportHHH-18168Resolved issue: HHH-18168Vladimír Kuruc
- Informix unique constraints on nullness columnsHHH-18153Resolved issue: HHH-18153Vladimír Kuruc
- Informix float and double precision in decimal digitsHHH-18150Resolved issue: HHH-18150Vladimír Kuruc
- Creation of temporary table leads to commit on H2HHH-17943Resolved issue: HHH-17943Andrea Boriero
- StoredProcedureQuery map result set incorrectly when having INOUT paramHHH-17847Resolved issue: HHH-17847Phuc Nguyen
- Fetch offset clause is getting added in the wrong place inside the sql native queryHHH-17784
- Composite IdClass containing a ManyToOne association malfunctions with cachesHHH-17440
- Possible regression - cannot call stored procedure from Spring Boot Data JPA - crosspostHHH-17426
- Regression in Hibernate 6 - New case of "Illegal combination of ordering and sorting annotations" exceptionHHH-17364
- NonUniqueResultException for HQL single entity select by id with join fetch and cachingHHH-17289Resolved issue: HHH-17289Marco Belladelli
- Teradata Dialect Issue Above Version 14HHH-17174Resolved issue: HHH-17174Christian Beikov
- Object serialization not working with @DiscriminatorColumn and KotlinHHH-17026
- Query for enum with IS NULL fails with NullPointerException (org.hibernate.metamodel.mapping.JdbcMapping.getJdbcValueBinder())HHH-17006Resolved issue: HHH-17006Gavin King
- CriteriaBuilder.equal(Expression any, null object): QueryException: Ordinal parameter not boundHHH-16828
- Regression with target type in CAST functionHHH-16521Resolved issue: HHH-16521Andrea Boriero
- Hibernate 6.0+ use the wrong logger name for logging the SQL dialectHHH-16507Resolved issue: HHH-16507Sven Strickroth
- SequenceStyleGenerator issue with hibernate 6HHH-16415
- PrePersist not executed with ManyToMany Jointable nested entityHHH-16300Resolved issue: HHH-16300
- [Envers] Schema Validation Failure With Audited (N)Clob Column with Hibernate 6 on H2HHH-16253
- CompositeUserType change in 6.0 make impossible to migrate multi-column mappingHHH-16232
- Error advancing (next) ResultSet position with Hibernate v6HHH-16120Resolved issue: HHH-16120Andrea Boriero
- Passing an ExtendedBeanManager which is notified too late leads to initialization errorHHH-16096Resolved issue: HHH-16096Vedran Prišćan
- Exception when find by association id that is a generic @EmbeddedId with @MappedSuperclassHHH-16070Resolved issue: HHH-16070Marco Belladelli
- Subquery with where condition on a column with columnDefinition results in wrong SQL grammarHHH-15805Resolved issue: HHH-15805Andrea Boriero
- Query bug in @NamedEntityGraph when doing Eager loading of @OneToOne mappings in Single Table inheritanceHHH-15622Resolved issue: HHH-15622Andrea Boriero
- @Table(fetch=SELECT) is gone from H6HHH-15565Resolved issue: HHH-15565Gavin King
- Stored Procedure, 'registerStoredProcedureParameter(..., ResultSet.class, ParameterMode.REF_CURSOR);' throws NPE : cannot invoke "org.hibernate.query.BindableType.getBindableJavaType()" because "parameterType" is nullHHH-15542Resolved issue: HHH-15542Andrea Boriero
- UUID with AttributeConverter, merge throws ClassCastExceptionHHH-15417Resolved issue: HHH-15417Christian Beikov
- CockroachDB LOBs should not be bound to stream operationsHHH-15382Resolved issue: HHH-15382Karel Maesen
- FirebirdDialect disappeared on Hibernate 6HHH-15377Resolved issue: HHH-15377
- Unable to get primary information on some dialects (ex: Oracle) when the PK column's position doesn't match the alphabetical name's orderHHH-15356Resolved issue: HHH-15356Andrea Boriero
- Inappropriate variation of HQL left join to SQL inner joinHHH-15342Resolved issue: HHH-15342Andrea Boriero
- Hibernate Gradle plugin is not working for Kotlin projectsHHH-15314Resolved issue: HHH-15314Steve Ebersole
- Testing apiHHH-15309Resolved issue: HHH-15309
- Invalid Automatic-Module-Name org.hibernate.orm.community-dialectsHHH-15297Resolved issue: HHH-15297Andrea Boriero
- testingHHH-15296Resolved issue: HHH-15296
- Type issues in CockroachDB dialectHHH-15294Resolved issue: HHH-15294Karel Maesen
- CockroachDB BYTES type does not have a length specificationHHH-15293Resolved issue: HHH-15293Karel Maesen
- ClassCastException Regression in CriteriaBuilderHHH-15291Resolved issue: HHH-15291Christian Beikov
- NullPointerException from EntityManager.createNamedNativeQuery(…)HHH-15283Resolved issue: HHH-15283Nathan Xu
- Explicitly add JavaDoc to make @deprecated hint visible in EclipseHHH-15259Resolved issue: HHH-15259Sven Strickroth
- Fix org.hibernate.orm.test.batch.BatchTestHHH-15255Resolved issue: HHH-15255Nathan Xu
- Enable JMH benchmark for Hibernate Core in v6HHH-15253Resolved issue: HHH-15253Nathan Xu
Important performance degration on flush in Hibernate 6
Description
Attachments
Details
Details
Assignee
Reporter
Worked in
Components
Priority
Activity
Gavin King 40 minutes ago
the first one most of the time incurs no cost because it’s a noop but the second one will go through all entities managed or readonly (well after your patch above, it will just be managed entities).
OK, now I see the source of the issue. Easy fix, I believe.
Gavin King 1 hour ago
This will help for readonly entities I guess, but not for managed one?
Correct.
Victor Noël 2 hours agoEdited
Thanks for the explanation, I agree I’m not going to rock the world with my 1h reading of the code ^^
Anyway, you can try this out and see if it helps: https://github.com/hibernate/hibernate-orm/pull/10096
This will help for readonly entities I guess, but not for managed one?
We have to read all fields of a managed entity at flush time anyway, because we have to dirty check them. So this could not possibly be responsible for a 10x slowdown
So just to be clear, I believe the slow down is caused by the addition of this code: https://github.com/hibernate/hibernate-orm/pull/8515/files#diff-b0bb2d87486d2105bfe77236eaef49bcf1d4dff9ad84491cf5101e976dd77136R164. In org.hibernate.event.internal.AbstractFlushingEventListener#prepareEntityFlushes
there are two loops, the first one most of the time incurs no cost because it’s a noop but the second one will go through all entities managed or readonly (well after your patch above, it will just be managed entities). I am not saying this code is not correct of course, but that’s what is causing that slow down.
This is with Hibernate 5:
This is with Hibernate 6:
So as you can see in the second screenshot, not bytecode optimization happens as you mentioned, so I see an opportunity for me to enable something that is not currently enabled. Could you maybe tell me what should be done to enable this? Right now I am using the compile time bytecode enhancement (enableLazyInitialization
=true, enableDirtyTracking
=true but surprisingly enableAssociationManagement
=false and not true…).
Disabling all of this would give us a good information then? That’s what I will try for now.
Is there anything else I could manually enable to get this “reflection optimizer”?
Gavin King 3 hours ago
Anyway, you can try this out and see if it helps: https://github.com/hibernate/hibernate-orm/pull/10096
Gavin King 3 hours ago
Also, I wanted to point out that when I did a bit of debugging, I noticed that, for MANAGED entities, the code in
Cascade.cascade
goes through each and every field, even those that couldn’t be cascaded at all I think and would fetch their values using reflection (which accounted for ~66% of the time spent in this method) for nothing in the end
I don’t know what code you’re referring to here (line number?) but I think you’re making a lot of assumptions here. A couple of comments:
We have to read all fields of a managed entity at flush time anyway, because we have to dirty check them. So this could not possibly be responsible for a 10x slowdown.
Reading a several fields (even by reflection) and putting their values in a perfectly pre-sized array is not usually a particularly expensive operation compared to everything else Hibernate has to do at flush-time, and in case it is, Hibernate can use a “reflection optimizer” which uses bytecode generation to eliminate the reflection. I’ve personally never once heard of anyone turning on the reflection optimizer and observing a significant increase in performance. (Not saying it’s impossible for that to happen in specific cases.)
would check all fields of entities even when using dirty checking bytecode enhancement
If I were you I would turn off bytecode enhancement and see what happens. Let me know if your program gets faster or slower.
Do you think there are opportunity for improving performance
I mean, y’know, maybe, but I never believe in any “performance bug” or “performance optimization” that arises from someone eyeballing code in the debugger. I don’t trust my own intuitions about performance, let alone anyone else’s. I want to see actual numbers.
Hi,
I am migrating from Hibernate 5 to Hibernate 6 and noticed huge performance degradation during flush when there are many managed entities in the session (in some cases we went from 1mn of flush to 10mn of flush because of this).
It is caused by the change introduced in https://hibernate.atlassian.net/browse/HHH-6999 in
org.hibernate.event.internal.AbstractFlushingEventListener#prepareEntityFlushes
: https://github.com/hibernate/hibernate-orm/pull/8515/files#diff-b0bb2d87486d2105bfe77236eaef49bcf1d4dff9ad84491cf5101e976dd77136R164Basically what happens is the following:
the second loop is calling
Cascade.cascade
on every entity currently in sessioneven though
enhancedForLazyLoading
is true, we end up settingdirtyAttributes
tonull
and then EACH and EVERY field of the entry are checked one by one to see if they changed
The code is too hard for me to understand to just propose a solution, but if anybody shares with me how this is meant to work and what a solution would look like, I can try contributing.
Also any workaround for this would be greatly appreciated :)