Skip to content

Commit 7d78b00

Browse files
committed
document the differnce in semantics of FlushMode.AUTO between JPA bootstrap and native Hibernate
1 parent 3c67006 commit 7d78b00

File tree

3 files changed

+28
-20
lines changed

3 files changed

+28
-20
lines changed

hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ public interface SessionFactoryOptions extends QueryEngineOptions {
9292
JpaCompliance getJpaCompliance();
9393

9494
/**
95-
* Was building of the SessionFactory initiated through JPA bootstrapping, or
96-
* through Hibernate's native bootstrapping?
95+
* Was building of the {@link org.hibernate.SessionFactory} initiated through JPA
96+
* bootstrapping, or through Hibernate-native bootstrapping?
9797
*
9898
* @return {@code true} indicates the SessionFactory was built through JPA
9999
* bootstrapping; {@code false} indicates it was built through native bootstrapping.

hibernate-core/src/main/java/org/hibernate/query/NativeQuery.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@
8282
* {@link #addSynchronizedEntityName}, or
8383
* {@link #addSynchronizedQuerySpace}.
8484
* </ul>
85+
* <p>
86+
* When the affected tables are not known to Hibernate, the behavior depends
87+
* on whether Hibernate is operating in fully JPA-compliant mode.
88+
* <ul>
89+
* <li>In JPA-compliant mode, {@link FlushModeType#AUTO} specifies that the
90+
* session should be flushed before execution of a native query when the
91+
* affected tables are not known.
92+
* <li>Otherwise, when Hibernate is not operating in JPA-compliant mode,
93+
* {@code AUTO} specifies that the session is <em>not</em> flushed before
94+
* execution of a native query, unless the affected tables are known and
95+
* Hibernate determines that a flush is required.
96+
* </ul>
8597
*
8698
* @author Gavin King
8799
* @author Steve Ebersole

hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -643,31 +643,27 @@ private boolean startsWithSelect() {
643643

644644
@Override
645645
protected void prepareForExecution() {
646-
if ( getSynchronizedQuerySpaces() != null && !getSynchronizedQuerySpaces().isEmpty() ) {
647-
// The application defined query spaces on the Hibernate NativeQuery
648-
// which means the query will already perform a partial flush
649-
// according to the defined query spaces, no need to do a full flush.
650-
return;
651-
}
652-
653-
// otherwise we need to flush. the query itself is not required to execute
654-
// in a transaction; if there is no transaction, the flush would throw a
655-
// TransactionRequiredException which would potentially break existing
656-
// apps, so we only do the flush if a transaction is in progress.
657-
//
658-
// NOTE : this was added for JPA initially. Perhaps we want to only do
659-
// this from JPA usage?
660-
if ( shouldFlush() ) {
661-
getSession().flush();
646+
if ( getSynchronizedQuerySpaces() == null || getSynchronizedQuerySpaces().isEmpty() ) {
647+
// We need to flush. The query itself is not required to execute in a
648+
// transaction; if there is no transaction, the flush would throw a
649+
// TransactionRequiredException which would potentially break existing
650+
// apps, so we only do the flush if a transaction is in progress.
651+
if ( shouldFlush() ) {
652+
getSession().flush();
653+
}
654+
// Reset the callback before every execution
655+
callback = null;
662656
}
663-
// Reset the callback before every execution
664-
callback = null;
657+
// Otherwise, the application specified query spaces via the Hibernate
658+
// SynchronizeableQuery and so the query will already perform a partial
659+
// flush according to the defined query spaces - no need for a full flush.
665660
}
666661

667662
private boolean shouldFlush() {
668663
if ( getSession().isTransactionInProgress() ) {
669664
final FlushMode flushMode = getQueryOptions().getFlushMode();
670665
return switch ( flushMode == null ? getSession().getHibernateFlushMode() : flushMode ) {
666+
// The JPA spec requires that we auto-flush before native queries
671667
case AUTO -> getSession().getFactory().getSessionFactoryOptions().isJpaBootstrap();
672668
case ALWAYS -> true;
673669
default -> false;

0 commit comments

Comments
 (0)