Skip to content
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

Hibernate 5 SpringSessionSynchronization calls Session.getFlushMode() directly instead of using SessionFactoryUtils.getFlushMode(session) [SPR-14364] #18936

Closed
spring-issuemaster opened this issue Jun 14, 2016 · 5 comments
Assignees
Milestone

Comments

@spring-issuemaster
Copy link
Collaborator

@spring-issuemaster spring-issuemaster commented Jun 14, 2016

Manuel Dominguez Sarmiento opened SPR-14364 and commented

Hibernate 5.2.0 changed the method signature for Session.getFlushMode() so that it returns a javax.persistence.FlushModeType instead of a org.hibernate.FlushMode

Spring 4.3.0 introduced several changes so that it could remain compatible with both 5.1.0 and 5.2.0 mainly by introducing indirection to obtain the Hibernate flush mode through SessionFactoryUtils.getFlushMode(session). However, this necessary change was omitted from SpringSessionSynchronization which still uses the following code snippet in beforeCommit():

if (!session.getFlushMode().equals(FlushMode.MANUAL)) { ... }

which should now be:

FlushMode flushMode = SessionFactoryUtils.getFlushMode(session);
if (FlushMode.MANUAL.equals(flushMode)) { ... }

This has critical consequences. Due to this bug, Spring 4.3.0 is not compatible with either Hibernate 5.1.0 nor 5.2.0

When using Hibernate 5.1.0 this bug causes a java.lang.NoSuchMethodError due to the method signature change:

java.lang.NoSuchMethodError: org.hibernate.Session.getFlushMode()Ljavax/persistence/FlushModeType;
at org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:101)

While in Hibernate 5.2.0 this causes javax.persistence.TransactionRequiredException due to equals(FlushMode.MANUAL) always returning false since it is comparing javax.persistence.FlushModeType vs org.hibernate.FlushMode

javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3392)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1385)
at org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:104)


Affects: 4.3 GA

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jun 14, 2016

Manuel Dominguez Sarmiento commented

Changes introduced in Spring 4.3.0
9394616

Issue related to (sorry it seems I don't have permissions to set links between issues):
#18899

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jun 14, 2016

Juergen Hoeller commented

This unfortunately escaped our testing since the affected code path only runs in JTA scenarios, i.e. not with common HibernateTransactionManager usage. In any case, fixed for 4.3.1 now.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jun 14, 2016

Manuel Dominguez Sarmiento commented

We don't use JTA and we ran into this issue. We're using org.springframework.orm.hibernate5.HibernateTransactionManager

The code path is through TransactionSynchronizationUtils.triggerBeforeCommit() which in turn is invoked by AbstractPlatformTransactionManager.triggerBeforeCommit() so effectively it affects non-JTA setups as well.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jun 14, 2016

Juergen Hoeller commented

My point is that SpringSessionSynchronization only gets involved for a non-synchronized Session that our SpringSessionContext encounters on SessionFactory.getCurrentSession() calls. This is usually the case with JTA or in other lazy creation scenarios such as with SUPPORTS propagation, whereas HibernateTransactionManager exposes pre-synchronized Sessions for regularly demarcated transactions with REQUIRED propagation upfront.

That's just a side note anyway. This is fixed for 4.3.1 now, scheduled for release on July 1st, and will be available in the upcoming 4.3.1.BUILD-SNAPSHOT already.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jun 14, 2016

Manuel Dominguez Sarmiento commented

That makes sense. We were running into this for some transactions, but not in others. So the kind of propagation surely comes into play. Thanks for looking at this promptly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.