Skip to content

Commit 3818b6d

Browse files
committed
HHH-17971 - Remove ALLOW_REFRESH_DETACHED_ENTITY
Signed-off-by: Jan Schatteman <[email protected]>
1 parent 2be3000 commit 3818b6d

File tree

34 files changed

+122
-872
lines changed

34 files changed

+122
-872
lines changed

documentation/src/main/asciidoc/userguide/chapters/pc/PersistenceContext.adoc

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -886,16 +886,7 @@ See the discussion of non-identifier <<chapters/domain/basic_types.adoc#mapping-
886886
[IMPORTANT]
887887
====
888888
Traditionally, Hibernate allowed detached entities to be refreshed.
889-
Unfortunately, Jakarta Persistence prohibits this practice and specifies that an `IllegalArgumentException` should be thrown instead.
890-
891-
For this reason, when bootstrapping the Hibernate `SessionFactory` using the native API, the legacy detached entity refresh behavior is going to be preserved.
892-
On the other hand, when bootstrapping Hibernate through the Jakarta Persistence `EntityManagerFactory` building process, detached entities are not allowed to be refreshed by default.
893-
894-
However, this default behavior can be overwritten through the `hibernate.allow_refresh_detached_entity` configuration property.
895-
If this property is explicitly set to `true`, then you can refresh detached entities even when using the Jakarta Persistence bootstraps mechanism, therefore bypassing the Jakarta Persistence specification restriction.
896-
897-
For more about the `hibernate.allow_refresh_detached_entity` configuration property,
898-
check out the <<appendices/Configurations.adoc#misc,Configurations>> section as well.
889+
however, Jakarta Persistence prohibits this practice and specifies that an `IllegalArgumentException` should be thrown instead. This is the default behaviour from version 7.0 onwards.
899890
====
900891

901892
[[pc-refresh-gotchas]]

hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -426,11 +426,6 @@ public SessionFactoryBuilder applyXmlFormatMapper(FormatMapper xmlFormatMapper)
426426
return this;
427427
}
428428

429-
@Override
430-
public void disableRefreshDetachedEntity() {
431-
this.optionsBuilder.disableRefreshDetachedEntity();
432-
}
433-
434429
@Override
435430
public void disableJtaTransactionAccess() {
436431
this.optionsBuilder.disableJtaTransactionAccess();

hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
import jakarta.persistence.criteria.Nulls;
7676

7777
import static org.hibernate.cfg.AvailableSettings.ALLOW_JTA_TRANSACTION_ACCESS;
78-
import static org.hibernate.cfg.AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY;
7978
import static org.hibernate.cfg.AvailableSettings.ALLOW_UPDATE_OUTSIDE_TRANSACTION;
8079
import static org.hibernate.cfg.AvailableSettings.AUTO_CLOSE_SESSION;
8180
import static org.hibernate.cfg.AvailableSettings.AUTO_EVICT_COLLECTION_CACHE;
@@ -176,7 +175,6 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
176175
private boolean jtaTransactionAccessEnabled;
177176
private boolean allowOutOfTransactionUpdateOperations;
178177
private boolean releaseResourcesOnCloseEnabled;
179-
private boolean allowRefreshDetachedEntity;
180178

181179
// (JTA) transaction handling
182180
private boolean jtaTrackByThread;
@@ -335,12 +333,6 @@ public SessionFactoryOptionsBuilder(StandardServiceRegistry serviceRegistry, Boo
335333
true
336334
);
337335

338-
this.allowRefreshDetachedEntity = configurationService.getSetting(
339-
ALLOW_REFRESH_DETACHED_ENTITY,
340-
BOOLEAN,
341-
false
342-
);
343-
344336
this.flushBeforeCompletionEnabled = configurationService.getSetting( FLUSH_BEFORE_COMPLETION, BOOLEAN, true );
345337
this.autoCloseSessionEnabled = configurationService.getSetting( AUTO_CLOSE_SESSION, BOOLEAN, false );
346338

@@ -906,11 +898,6 @@ public boolean isJtaTransactionAccessEnabled() {
906898
return jtaTransactionAccessEnabled;
907899
}
908900

909-
@Override
910-
public boolean isAllowRefreshDetachedEntity() {
911-
return allowRefreshDetachedEntity;
912-
}
913-
914901
@Override
915902
public boolean isAllowOutOfTransactionUpdateOperations() {
916903
return allowOutOfTransactionUpdateOperations;
@@ -1624,10 +1611,6 @@ public void enableCollectionInDefaultFetchGroup(boolean enabled) {
16241611
this.collectionsInDefaultFetchGroupEnabled = enabled;
16251612
}
16261613

1627-
public void disableRefreshDetachedEntity() {
1628-
this.allowRefreshDetachedEntity = false;
1629-
}
1630-
16311614
public void disableJtaTransactionAccess() {
16321615
this.jtaTransactionAccessEnabled = false;
16331616
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737

3838
import jakarta.persistence.criteria.Nulls;
3939

40+
import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER;
41+
4042
/**
4143
* Convenience base class for custom implementations of {@link SessionFactoryOptions}
4244
* using delegation.
@@ -77,8 +79,13 @@ public boolean isJtaTransactionAccessEnabled() {
7779
return delegate.isJtaTransactionAccessEnabled();
7880
}
7981

82+
/**
83+
* @deprecated with no replacement.
84+
*/
85+
@Deprecated(since = "7.0", forRemoval = true)
8086
@Override
8187
public boolean isAllowRefreshDetachedEntity() {
88+
DEPRECATION_LOGGER.deprecatedRefreshLockDetachedEntity();
8289
return delegate.isAllowRefreshDetachedEntity();
8390
}
8491

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package org.hibernate.boot.spi;
66

77
import org.hibernate.boot.SessionFactoryBuilder;
8+
import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER;
89

910
/**
1011
* Additional SPI contract for {@link SessionFactoryBuilder}, mainly intended for
@@ -21,10 +22,11 @@ public interface SessionFactoryBuilderImplementor extends SessionFactoryBuilder
2122
void disableJtaTransactionAccess();
2223

2324
/**
24-
* Called if {@link org.hibernate.cfg.AvailableSettings#ALLOW_REFRESH_DETACHED_ENTITY}
25-
* is not enabled.
25+
* @deprecated with no replacement.
2626
*/
27+
@Deprecated(since = "7.0", forRemoval = true)
2728
default void disableRefreshDetachedEntity() {
29+
DEPRECATION_LOGGER.deprecatedRefreshLockDetachedEntity();
2830
}
2931

3032
/**

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434

3535
import jakarta.persistence.criteria.Nulls;
3636

37+
import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER;
38+
3739
/**
3840
* Aggregator of special options used to build the {@link org.hibernate.SessionFactory}.
3941
*
@@ -76,7 +78,12 @@ public interface SessionFactoryOptions extends QueryEngineOptions {
7678

7779
boolean isJtaTransactionAccessEnabled();
7880

81+
/**
82+
* @deprecated with no replacement.
83+
*/
84+
@Deprecated(since = "7.0", forRemoval = true)
7985
default boolean isAllowRefreshDetachedEntity() {
86+
DEPRECATION_LOGGER.deprecatedRefreshLockDetachedEntity();
8087
return false;
8188
}
8289

hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -120,24 +120,6 @@ public interface AvailableSettings
120120
*/
121121
String DELAY_ENTITY_LOADER_CREATIONS = "hibernate.loader.delay_entity_loader_creations";
122122

123-
/**
124-
* When enabled, allows calls to {@link jakarta.persistence.EntityManager#refresh(Object)}
125-
* and {@link org.hibernate.Session#refresh(Object)} on a detached entity instance.
126-
* <p>
127-
* Values are {@code true}, which allows refreshing a detached instance and {@code false},
128-
* which does not. When refreshing is disallowed, an {@link IllegalArgumentException}
129-
* is thrown.
130-
* <p>
131-
* The default behavior is to allow refreshing a detached instance unless Hibernate
132-
* is bootstrapped via JPA.
133-
*
134-
* @deprecated Will be removed with no replacement from ORM version 7 onwards
135-
*
136-
* @since 5.2
137-
*/
138-
@Deprecated(since="6.6", forRemoval = true)
139-
String ALLOW_REFRESH_DETACHED_ENTITY = "hibernate.allow_refresh_detached_entity";
140-
141123
/**
142124
* Specifies how Hibernate should behave when multiple representations of the same
143125
* persistent entity instance, that is, multiple detached objects with the same

hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,10 +1245,8 @@ private void fireRefresh(final RefreshContext refreshedAlready, final RefreshEve
12451245
}
12461246

12471247
private void checkEntityManaged(String entityName, Object entity) {
1248-
if ( !getSessionFactory().getSessionFactoryOptions().isAllowRefreshDetachedEntity() ) {
1249-
if ( !managed( entityName, entity ) ) {
1250-
throw new IllegalArgumentException( "Given entity is not associated with the persistence context" );
1251-
}
1248+
if ( !managed( entityName, entity ) ) {
1249+
throw new IllegalArgumentException( "Given entity is not associated with the persistence context" );
12521250
}
12531251
}
12541252

hibernate-core/src/main/java/org/hibernate/internal/log/DeprecationLogger.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,11 @@ void recognizedObsoleteHibernateNamespace(
187187
value = "Encountered use of deprecated annotation [%s] at %s."
188188
)
189189
void deprecatedAnnotation(Class<? extends Annotation> annotationType, String locationDescription);
190+
191+
@LogMessage(level = WARN)
192+
@Message(
193+
id = 90000034,
194+
value = "Refreshing/locking detached entities is no longer allowed."
195+
)
196+
void deprecatedRefreshLockDetachedEntity();
190197
}

hibernate-core/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,7 +1479,6 @@ protected SessionFactoryBuilder populateSessionFactoryBuilder() {
14791479
// builder.applyInterceptor( sessionFactoryInterceptor );
14801480
// }
14811481
handleAllowJtaTransactionAccess( builder );
1482-
handleAllowDetachedEntity( builder );
14831482
addConfiguredSessionFactoryObserver( builder );
14841483
builder.addSessionFactoryObservers( ServiceRegistryCloser.INSTANCE );
14851484
builder.applyEntityNotFoundDelegate( JpaEntityNotFoundDelegate.INSTANCE );
@@ -1500,16 +1499,6 @@ private void addConfiguredSessionFactoryObserver(SessionFactoryBuilder builder)
15001499
}
15011500
}
15021501

1503-
// will use user override value or default to false if not supplied to follow JPA spec
1504-
private void handleAllowDetachedEntity(SessionFactoryBuilder builder) {
1505-
final boolean allowRefreshDetachedEntity =
1506-
readBooleanConfigurationValue( AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY );
1507-
if ( !allowRefreshDetachedEntity
1508-
&& builder instanceof SessionFactoryBuilderImplementor implementor ) {
1509-
implementor.disableRefreshDetachedEntity();
1510-
}
1511-
}
1512-
15131502
// will use user override value or default to false if not supplied to follow JPA spec
15141503
private void handleAllowJtaTransactionAccess(SessionFactoryBuilder builder) {
15151504
final boolean jtaTransactionAccessEnabled =

0 commit comments

Comments
 (0)