HHH-18169 disallow refresh/lock for detached instance
Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
parent
1d12dc0499
commit
7422c18a94
|
@ -933,44 +933,6 @@ And finally, serialization will make the deserialized form be detached (the orig
|
|||
|
||||
Detached data can still be manipulated, however, the persistence context will no longer automatically know about these modifications, and the application will need to intervene to make the changes persistent again.
|
||||
|
||||
[[pc-detach-reattach]]
|
||||
==== Reattaching detached data
|
||||
|
||||
Reattachment is the process of taking an incoming entity instance that is in the detached state and re-associating it with the current persistence context.
|
||||
|
||||
[IMPORTANT]
|
||||
====
|
||||
Jakarta Persistence does not support reattaching detached data. This is only available through Hibernate `org.hibernate.Session`.
|
||||
====
|
||||
|
||||
[[pc-detach-reattach-lock-example]]
|
||||
.Reattaching a detached entity using `lock`
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{example-dir-pc}/PersistenceContextTest.java[tags=pc-detach-reattach-lock-example]
|
||||
----
|
||||
====
|
||||
|
||||
[[pc-detach-reattach-saveOrUpdate-example]]
|
||||
.Reattaching a detached entity using `saveOrUpdate`
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{example-dir-pc}/PersistenceContextTest.java[tags=pc-detach-reattach-saveOrUpdate-example]
|
||||
----
|
||||
====
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
The method name `update` is a bit misleading here.
|
||||
It does not mean that an `SQL` `UPDATE` is immediately performed.
|
||||
It does, however, mean that an `SQL` `UPDATE` will be performed when the persistence context is flushed since Hibernate does not know its previous state against which to compare for changes.
|
||||
If the entity is mapped with `select-before-update`, Hibernate will pull the current state from the database and see if an update is needed.
|
||||
====
|
||||
|
||||
Provided the entity is detached, `update` and `saveOrUpdate` operate exactly the same.
|
||||
|
||||
[[pc-merge]]
|
||||
==== Merging detached data
|
||||
|
||||
|
@ -1274,17 +1236,6 @@ include::{example-dir-pc}/CascadeDetachTest.java[tags=pc-cascade-detach-example]
|
|||
Although unintuitively, `CascadeType.LOCK` does not propagate a lock request from a parent entity to its children.
|
||||
Such a use case requires the use of the `PessimisticLockScope.EXTENDED` value of the `jakarta.persistence.lock.scope` property.
|
||||
|
||||
However, `CascadeType.LOCK` allows us to reattach a parent entity along with its children to the currently running Persistence Context.
|
||||
|
||||
[[pc-cascade-lock-example]]
|
||||
.`CascadeType.LOCK` example
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{example-dir-pc}/CascadeLockTest.java[tags=pc-cascade-lock-example]
|
||||
----
|
||||
====
|
||||
|
||||
[[pc-cascade-refresh]]
|
||||
==== `CascadeType.REFRESH`
|
||||
|
||||
|
|
|
@ -337,7 +337,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
|||
this.allowRefreshDetachedEntity = configurationService.getSetting(
|
||||
ALLOW_REFRESH_DETACHED_ENTITY,
|
||||
BOOLEAN,
|
||||
true
|
||||
false
|
||||
);
|
||||
|
||||
this.flushBeforeCompletionEnabled = configurationService.getSetting( FLUSH_BEFORE_COMPLETION, BOOLEAN, true );
|
||||
|
|
|
@ -659,6 +659,7 @@ public class SessionImpl
|
|||
|
||||
private void fireLock(LockEvent event) {
|
||||
checkOpen();
|
||||
checkEntityManaged( event.getEntityName(), event.getObject() );
|
||||
pulseTransactionCoordinator();
|
||||
fastSessionServices.eventListenerGroup_LOCK
|
||||
.fireEventOnEachListener( event, LockEventListener::onLock );
|
||||
|
@ -1163,18 +1164,7 @@ public class SessionImpl
|
|||
|
||||
private void fireRefresh(final RefreshEvent event) {
|
||||
try {
|
||||
if ( !getSessionFactory().getSessionFactoryOptions().isAllowRefreshDetachedEntity() ) {
|
||||
if ( event.getEntityName() != null ) {
|
||||
if ( !contains( event.getEntityName(), event.getObject() ) ) {
|
||||
throw new IllegalArgumentException( "Entity not managed" );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( !contains( event.getObject() ) ) {
|
||||
throw new IllegalArgumentException( "Entity not managed" );
|
||||
}
|
||||
}
|
||||
}
|
||||
checkEntityManaged( event.getEntityName(), event.getObject() );
|
||||
pulseTransactionCoordinator();
|
||||
fastSessionServices.eventListenerGroup_REFRESH
|
||||
.fireEventOnEachListener( event, RefreshEventListener::onRefresh );
|
||||
|
@ -1195,6 +1185,7 @@ public class SessionImpl
|
|||
|
||||
private void fireRefresh(final RefreshContext refreshedAlready, final RefreshEvent event) {
|
||||
try {
|
||||
checkEntityManaged( event.getEntityName(), event.getObject() );
|
||||
pulseTransactionCoordinator();
|
||||
fastSessionServices.eventListenerGroup_REFRESH
|
||||
.fireEventOnEachListener( event, refreshedAlready, RefreshEventListener::onRefresh );
|
||||
|
@ -1207,6 +1198,18 @@ public class SessionImpl
|
|||
}
|
||||
}
|
||||
|
||||
private void checkEntityManaged(String entityName, Object entity) {
|
||||
if ( !getSessionFactory().getSessionFactoryOptions().isAllowRefreshDetachedEntity() ) {
|
||||
if ( !managed( entityName, entity ) ) {
|
||||
throw new IllegalArgumentException(
|
||||
"Given entity is not associated with the persistence context" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean managed(String entityName, Object entity) {
|
||||
return entityName == null ? contains( entity ) : contains( entityName, entity );
|
||||
}
|
||||
|
||||
// replicate() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -86,7 +86,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||
import static org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer.UNFETCHED_PROPERTY;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
|
||||
import static org.hibernate.internal.log.LoggingHelper.toLoggableString;
|
||||
import static org.hibernate.metamodel.mapping.ForeignKeyDescriptor.Nature.TARGET;
|
||||
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
|
||||
|
||||
|
@ -163,12 +162,9 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
lockMode = rowProcessingState.determineEffectiveLockMode( initializer.sourceAlias );
|
||||
if ( initializer.isResultInitializer() ) {
|
||||
uniqueKeyAttributePath = rowProcessingState.getEntityUniqueKeyAttributePath();
|
||||
if ( uniqueKeyAttributePath != null ) {
|
||||
uniqueKeyPropertyTypes = initializer.getParentEntityAttributeTypes( uniqueKeyAttributePath );
|
||||
}
|
||||
else {
|
||||
uniqueKeyPropertyTypes = null;
|
||||
}
|
||||
uniqueKeyPropertyTypes = uniqueKeyAttributePath != null
|
||||
? initializer.getParentEntityAttributeTypes( uniqueKeyAttributePath )
|
||||
: null;
|
||||
canUseEmbeddedIdentifierInstanceAsEntity = rowProcessingState.getEntityId() != null
|
||||
&& initializer.couldUseEmbeddedIdentifierInstanceAsEntity;
|
||||
}
|
||||
|
@ -178,13 +174,10 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
canUseEmbeddedIdentifierInstanceAsEntity = false;
|
||||
}
|
||||
hasCallbackActions = rowProcessingState.hasCallbackActions();
|
||||
if ( initializer.discriminatorAssembler == null
|
||||
|| rowProcessingState.isQueryCacheHit() && entityDescriptor.useShallowQueryCacheLayout() && !entityDescriptor.storeDiscriminatorInShallowQueryCacheLayout() ) {
|
||||
defaultConcreteDescriptor = entityDescriptor;
|
||||
}
|
||||
else {
|
||||
defaultConcreteDescriptor = null;
|
||||
}
|
||||
defaultConcreteDescriptor =
|
||||
hasConcreteDescriptor( rowProcessingState, initializer.discriminatorAssembler, entityDescriptor )
|
||||
? entityDescriptor
|
||||
: null;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -206,6 +199,16 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
}
|
||||
}
|
||||
|
||||
private static boolean hasConcreteDescriptor(
|
||||
RowProcessingState rowProcessingState,
|
||||
BasicResultAssembler<?> discriminatorAssembler,
|
||||
EntityPersister entityDescriptor) {
|
||||
return discriminatorAssembler == null
|
||||
|| rowProcessingState.isQueryCacheHit()
|
||||
&& entityDescriptor.useShallowQueryCacheLayout()
|
||||
&& !entityDescriptor.storeDiscriminatorInShallowQueryCacheLayout();
|
||||
}
|
||||
|
||||
public EntityInitializerImpl(
|
||||
EntityResultGraphNode resultDescriptor,
|
||||
String sourceAlias,
|
||||
|
@ -229,8 +232,9 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
: entityDescriptor.getRootEntityDescriptor().getEntityPersister();
|
||||
keyTypeForEqualsHashCode = entityDescriptor.getIdentifierType().getTypeForEqualsHashCode();
|
||||
// The id can only be the entity instance if this is a non-aggregated id that has no containing class
|
||||
couldUseEmbeddedIdentifierInstanceAsEntity = entityDescriptor.getIdentifierMapping() instanceof CompositeIdentifierMapping
|
||||
&& !( (CompositeIdentifierMapping) entityDescriptor.getIdentifierMapping() ).hasContainingClass();
|
||||
couldUseEmbeddedIdentifierInstanceAsEntity =
|
||||
entityDescriptor.getIdentifierMapping() instanceof CompositeIdentifierMapping
|
||||
&& !( (CompositeIdentifierMapping) entityDescriptor.getIdentifierMapping() ).hasContainingClass();
|
||||
|
||||
this.navigablePath = resultDescriptor.getNavigablePath();
|
||||
this.sourceAlias = sourceAlias;
|
||||
|
@ -258,7 +262,8 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
hasKeyManyToOne = initializer != null && initializer.isLazyCapable();
|
||||
}
|
||||
|
||||
assert entityDescriptor.hasSubclasses() == (discriminatorFetch != null) : "Discriminator should only be fetched if the entity has subclasses";
|
||||
assert entityDescriptor.hasSubclasses() == (discriminatorFetch != null)
|
||||
: "Discriminator should only be fetched if the entity has subclasses";
|
||||
discriminatorAssembler = discriminatorFetch != null
|
||||
? (BasicResultAssembler<?>) discriminatorFetch.createAssembler( this, creationState )
|
||||
: null;
|
||||
|
@ -286,12 +291,16 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
final BitSet[] lazySets = new BitSet[subMappingTypes.size() + 1];
|
||||
final BitSet[] maybeLazySets = new BitSet[subMappingTypes.size() + 1];
|
||||
final MutabilityPlan[][] updatableAttributeMutabilityPlans = new MutabilityPlan[subMappingTypes.size() + 1][];
|
||||
assemblers[rootEntityDescriptor.getSubclassId()] = new DomainResultAssembler[rootEntityDescriptor.getNumberOfFetchables()];
|
||||
updatableAttributeMutabilityPlans[rootEntityDescriptor.getSubclassId()] = new MutabilityPlan[rootEntityDescriptor.getNumberOfAttributeMappings()];
|
||||
assemblers[rootEntityDescriptor.getSubclassId()] =
|
||||
new DomainResultAssembler[rootEntityDescriptor.getNumberOfFetchables()];
|
||||
updatableAttributeMutabilityPlans[rootEntityDescriptor.getSubclassId()] =
|
||||
new MutabilityPlan[rootEntityDescriptor.getNumberOfAttributeMappings()];
|
||||
|
||||
for ( EntityMappingType subMappingType : subMappingTypes ) {
|
||||
assemblers[subMappingType.getSubclassId()] = new DomainResultAssembler[subMappingType.getNumberOfFetchables()];
|
||||
updatableAttributeMutabilityPlans[subMappingType.getSubclassId()] = new MutabilityPlan[subMappingType.getNumberOfAttributeMappings()];
|
||||
assemblers[subMappingType.getSubclassId()] =
|
||||
new DomainResultAssembler[subMappingType.getNumberOfFetchables()];
|
||||
updatableAttributeMutabilityPlans[subMappingType.getSubclassId()] =
|
||||
new MutabilityPlan[subMappingType.getNumberOfAttributeMappings()];
|
||||
}
|
||||
|
||||
boolean hasLazySubInitializers = false;
|
||||
|
@ -345,7 +354,8 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
}
|
||||
for ( EntityMappingType subMappingType : declaringType.getSubMappingTypes() ) {
|
||||
assemblers[subMappingType.getSubclassId()][stateArrayPosition] = stateAssembler;
|
||||
updatableAttributeMutabilityPlans[subMappingType.getSubclassId()][stateArrayPosition] = updatableAttributeMutabilityPlans[subclassId][stateArrayPosition];
|
||||
updatableAttributeMutabilityPlans[subMappingType.getSubclassId()][stateArrayPosition] =
|
||||
updatableAttributeMutabilityPlans[subclassId][stateArrayPosition];
|
||||
if ( subInitializer != null ) {
|
||||
if ( subInitializers[subMappingType.getSubclassId()] == null ) {
|
||||
subInitializers[subMappingType.getSubclassId()] = new Initializer<?>[size];
|
||||
|
@ -355,12 +365,14 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
maybeLazySets[subMappingType.getSubclassId()] = new BitSet(size);
|
||||
}
|
||||
subInitializers[subMappingType.getSubclassId()][stateArrayPosition] = subInitializer;
|
||||
eagerSubInitializers[subMappingType.getSubclassId()][stateArrayPosition] = eagerSubInitializers[subclassId][stateArrayPosition];
|
||||
collectionContainingSubInitializers[subMappingType.getSubclassId()][stateArrayPosition] = collectionContainingSubInitializers[subclassId][stateArrayPosition];
|
||||
if (lazySets[subclassId].get( stateArrayPosition ) ) {
|
||||
eagerSubInitializers[subMappingType.getSubclassId()][stateArrayPosition] =
|
||||
eagerSubInitializers[subclassId][stateArrayPosition];
|
||||
collectionContainingSubInitializers[subMappingType.getSubclassId()][stateArrayPosition] =
|
||||
collectionContainingSubInitializers[subclassId][stateArrayPosition];
|
||||
if ( lazySets[subclassId].get( stateArrayPosition ) ) {
|
||||
lazySets[subMappingType.getSubclassId()].set( stateArrayPosition );
|
||||
}
|
||||
if (maybeLazySets[subclassId].get( stateArrayPosition ) ) {
|
||||
if ( maybeLazySets[subclassId].get( stateArrayPosition ) ) {
|
||||
maybeLazySets[subMappingType.getSubclassId()].set( stateArrayPosition );
|
||||
}
|
||||
}
|
||||
|
@ -411,9 +423,10 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
|
||||
this.assemblers = assemblers;
|
||||
this.subInitializers = subInitializers;
|
||||
this.subInitializersForResolveFromInitialized = rootEntityDescriptor.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading()
|
||||
? subInitializers
|
||||
: eagerSubInitializers;
|
||||
this.subInitializersForResolveFromInitialized =
|
||||
rootEntityDescriptor.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading()
|
||||
? subInitializers
|
||||
: eagerSubInitializers;
|
||||
this.collectionContainingSubInitializers = collectionContainingSubInitializers;
|
||||
this.lazySets = Arrays.stream( lazySets ).map( ImmutableBitSet::valueOf ).toArray( ImmutableBitSet[]::new );
|
||||
this.maybeLazySets = Arrays.stream( maybeLazySets )
|
||||
|
@ -531,7 +544,8 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
}
|
||||
else {
|
||||
//noinspection unchecked
|
||||
final Initializer<InitializerData> initializer = (Initializer<InitializerData>) identifierAssembler.getInitializer();
|
||||
final Initializer<InitializerData> initializer =
|
||||
(Initializer<InitializerData>) identifierAssembler.getInitializer();
|
||||
if ( initializer != null ) {
|
||||
final InitializerData subData = initializer.getData( rowProcessingState );
|
||||
initializer.resolveKey( subData );
|
||||
|
@ -785,7 +799,8 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
}
|
||||
|
||||
private void deepCopy(EntityPersister containerDescriptor, Object[] source, Object[] target) {
|
||||
final MutabilityPlan<Object>[] updatableAttributeMutabilityPlan = updatableAttributeMutabilityPlans[containerDescriptor.getSubclassId()];
|
||||
final MutabilityPlan<Object>[] updatableAttributeMutabilityPlan =
|
||||
updatableAttributeMutabilityPlans[containerDescriptor.getSubclassId()];
|
||||
for ( int i = 0; i < updatableAttributeMutabilityPlan.length; i++ ) {
|
||||
final Object sourceValue = source[i];
|
||||
if ( updatableAttributeMutabilityPlan[i] != null
|
||||
|
@ -830,11 +845,7 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
protected Type[] getParentEntityAttributeTypes(String attributeName) {
|
||||
Type[] types = parentEntityAttributeTypes.get( attributeName );
|
||||
if ( types == null ) {
|
||||
types = new Type[
|
||||
entityDescriptor.getRootEntityDescriptor()
|
||||
.getSubclassEntityNames()
|
||||
.size()
|
||||
];
|
||||
types = new Type[entityDescriptor.getRootEntityDescriptor().getSubclassEntityNames().size()];
|
||||
initializeAttributeType( types, entityDescriptor, attributeName );
|
||||
for ( EntityMappingType subMappingType : entityDescriptor.getSubMappingTypes() ) {
|
||||
initializeAttributeType( types, subMappingType.getEntityPersister(), attributeName );
|
||||
|
@ -855,12 +866,12 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
@Nullable BasicResultAssembler<?> discriminatorAssembler,
|
||||
EntityPersister entityDescriptor)
|
||||
throws WrongClassException {
|
||||
if ( discriminatorAssembler == null
|
||||
|| rowProcessingState.isQueryCacheHit() && entityDescriptor.useShallowQueryCacheLayout() && !entityDescriptor.storeDiscriminatorInShallowQueryCacheLayout() ) {
|
||||
if ( hasConcreteDescriptor( rowProcessingState, discriminatorAssembler, entityDescriptor ) ) {
|
||||
return entityDescriptor;
|
||||
}
|
||||
else {
|
||||
assert entityDescriptor.hasSubclasses() : "Reading a discriminator from a result set should only happen if the entity has subclasses";
|
||||
assert entityDescriptor.hasSubclasses()
|
||||
: "Reading a discriminator from a result set should only happen if the entity has subclasses";
|
||||
final EntityDiscriminatorMapping discriminatorMapping = entityDescriptor.getDiscriminatorMapping();
|
||||
assert discriminatorMapping != null;
|
||||
final Object discriminator = discriminatorAssembler.extractRawValue( rowProcessingState );
|
||||
|
@ -888,9 +899,16 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
}
|
||||
|
||||
protected boolean useEmbeddedIdentifierInstanceAsEntity(EntityInitializerData data) {
|
||||
return data.canUseEmbeddedIdentifierInstanceAsEntity
|
||||
&& ( data.concreteDescriptor = determineConcreteEntityDescriptor( data.getRowProcessingState(), discriminatorAssembler, entityDescriptor ) ) != null
|
||||
if ( data.canUseEmbeddedIdentifierInstanceAsEntity ) {
|
||||
data.concreteDescriptor =
|
||||
determineConcreteEntityDescriptor( data.getRowProcessingState(),
|
||||
discriminatorAssembler, entityDescriptor );
|
||||
return data.concreteDescriptor != null
|
||||
&& data.concreteDescriptor.isInstance( data.getRowProcessingState().getEntityId() );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -918,7 +936,7 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
resolveKey( data );
|
||||
assert data.getState() == State.MISSING;
|
||||
assert referencedModelPart instanceof ToOneAttributeMapping
|
||||
&& ( (ToOneAttributeMapping) referencedModelPart ).getSideNature() == TARGET;
|
||||
&& ( (ToOneAttributeMapping) referencedModelPart ).getSideNature() == TARGET;
|
||||
return;
|
||||
}
|
||||
// If the entity initializer is null, we know the entity is fully initialized,
|
||||
|
@ -1132,7 +1150,7 @@ public class EntityInitializerImpl extends AbstractInitializer<EntityInitializer
|
|||
|
||||
private boolean isProxyInstance(Object proxy) {
|
||||
return proxy != null
|
||||
&& ( proxy instanceof MapProxy || entityDescriptor.getJavaType().getJavaTypeClass().isInstance( proxy ) );
|
||||
&& ( proxy instanceof MapProxy || entityDescriptor.getJavaType().getJavaTypeClass().isInstance( proxy ) );
|
||||
}
|
||||
|
||||
private boolean isExistingEntityInitialized(Object existingEntity) {
|
||||
|
|
|
@ -8,11 +8,14 @@ package org.hibernate.orm.test.bytecode.enhancement.lazy.HHH_10708;
|
|||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.testing.bytecode.enhancement.extension.BytecodeEnhanced;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -33,6 +36,7 @@ import java.util.Set;
|
|||
)
|
||||
@SessionFactory
|
||||
@BytecodeEnhanced
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class UnexpectedDeleteTest2 {
|
||||
|
||||
private Bar myBar;
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.orm.test.bytecode.enhancement.lazy.backref;
|
|||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.util.SerializationHelper;
|
||||
import org.hibernate.orm.test.bytecode.enhancement.lazy.NoDirtyCheckingContext;
|
||||
|
@ -19,8 +20,10 @@ import org.hibernate.orm.test.collection.backref.map.compkey.Product;
|
|||
import org.hibernate.testing.bytecode.enhancement.CustomEnhancementContext;
|
||||
import org.hibernate.testing.bytecode.enhancement.extension.BytecodeEnhanced;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
@ -42,6 +45,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
@SessionFactory
|
||||
@BytecodeEnhanced
|
||||
@CustomEnhancementContext({ NoDirtyCheckingContext.class, DirtyCheckEnhancementContext.class })
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class BackrefCompositeMapKeyTest {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.orm.test.bytecode.enhancement.orphan;
|
|||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.bytecode.enhance.spi.DefaultEnhancementContext;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.internal.util.SerializationHelper;
|
||||
import org.hibernate.orm.test.orphan.Part;
|
||||
import org.hibernate.orm.test.orphan.Product;
|
||||
|
@ -18,8 +19,10 @@ import org.hibernate.testing.bytecode.enhancement.EnhancerTestContext;
|
|||
import org.hibernate.testing.bytecode.enhancement.extension.BytecodeEnhanced;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -41,6 +44,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
EnhancerTestContext.class, // supports laziness and dirty-checking
|
||||
DefaultEnhancementContext.class
|
||||
})
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class OrphanTest {
|
||||
|
||||
@AfterEach
|
||||
|
|
|
@ -23,10 +23,13 @@ import jakarta.persistence.Temporal;
|
|||
import jakarta.persistence.TemporalType;
|
||||
import org.hibernate.annotations.Fetch;
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -43,6 +46,7 @@ import static org.junit.Assert.assertEquals;
|
|||
}
|
||||
)
|
||||
@SessionFactory
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class RefreshTest {
|
||||
|
||||
private JobBatch batch;
|
||||
|
|
|
@ -8,12 +8,15 @@ package org.hibernate.orm.test.collection.backref.map.compkey;
|
|||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.util.SerializationHelper;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
@ -33,6 +36,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
)
|
||||
)
|
||||
@SessionFactory
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class BackrefCompositeMapKeyTest {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -301,7 +301,6 @@ public class SQLServerDialectTest extends BaseCoreFunctionalTestCase {
|
|||
session.persist( new Contact( 1L, "Lukasz", "Antoniak", "owner", folder1 ) );
|
||||
session.persist( new Contact( 2L, "Kinga", "Mroz", "co-owner", folder2 ) );
|
||||
session.flush();
|
||||
session.clear();
|
||||
session.refresh( folder1 );
|
||||
session.refresh( folder2 );
|
||||
session.clear();
|
||||
|
|
|
@ -65,6 +65,7 @@ public class ImmutableTest extends BaseSessionFactoryFunctionalTest {
|
|||
protected void applySettings(StandardServiceRegistryBuilder builer) {
|
||||
builer.applySetting( Environment.GENERATE_STATISTICS, "true" );
|
||||
builer.applySetting( Environment.STATEMENT_BATCH_SIZE, "0" );
|
||||
builer.applySetting( Environment.ALLOW_REFRESH_DETACHED_ENTITY, "true" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -11,13 +11,16 @@ import java.util.Iterator;
|
|||
import org.hibernate.LockMode;
|
||||
import org.hibernate.StaleObjectStateException;
|
||||
import org.hibernate.StaleStateException;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.metamodel.MappingMetamodel;
|
||||
|
||||
import org.hibernate.testing.orm.junit.FailureExpected;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -40,6 +43,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
* @author Gail Badner
|
||||
*/
|
||||
@SessionFactory(generateStatistics = true)
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public abstract class AbstractEntityWithManyToManyTest {
|
||||
private boolean isPlanContractsInverse;
|
||||
private boolean isPlanContractsBidirectional;
|
||||
|
|
|
@ -14,9 +14,12 @@ import jakarta.persistence.criteria.Root;
|
|||
|
||||
import org.hibernate.LockMode;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -34,6 +37,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
xmlMappings = "org/hibernate/orm/test/joinedsubclass/Person.hbm.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class JoinedSubclassTest {
|
||||
|
||||
@AfterEach
|
||||
|
|
|
@ -15,9 +15,11 @@ import org.hibernate.LockMode;
|
|||
import org.hibernate.Session;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.testing.orm.junit.Jpa;
|
||||
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
@ -25,10 +27,9 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Jpa(annotatedClasses = {
|
||||
MergeWithTransientNonCascadedAssociationTest.Person.class,
|
||||
MergeWithTransientNonCascadedAssociationTest.Address.class
|
||||
})
|
||||
@Jpa(annotatedClasses = {MergeWithTransientNonCascadedAssociationTest.Person.class,
|
||||
MergeWithTransientNonCascadedAssociationTest.Address.class},
|
||||
properties = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class MergeWithTransientNonCascadedAssociationTest {
|
||||
@Test
|
||||
public void testMergeWithTransientNonCascadedAssociation(EntityManagerFactoryScope scope) {
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
*/
|
||||
package org.hibernate.orm.test.mapping.naturalid.mutable.cached;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
|
||||
|
||||
import static org.hibernate.cfg.AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY;
|
||||
import static org.hibernate.cfg.AvailableSettings.GENERATE_STATISTICS;
|
||||
import static org.hibernate.cfg.AvailableSettings.USE_SECOND_LEVEL_CACHE;
|
||||
import static org.hibernate.testing.cache.CachingRegionFactory.DEFAULT_ACCESSTYPE;
|
||||
|
@ -20,7 +22,8 @@ import static org.hibernate.testing.cache.CachingRegionFactory.DEFAULT_ACCESSTYP
|
|||
settings = {
|
||||
@Setting( name = USE_SECOND_LEVEL_CACHE, value = "true" ),
|
||||
@Setting( name = DEFAULT_ACCESSTYPE, value = "nonstrict-read-write" ),
|
||||
@Setting( name = GENERATE_STATISTICS, value = "true" )
|
||||
@Setting( name = GENERATE_STATISTICS, value = "true" ),
|
||||
@Setting( name = ALLOW_REFRESH_DETACHED_ENTITY, value = "true" )
|
||||
}
|
||||
)
|
||||
@DomainModel( annotatedClasses = {A.class, Another.class, AllCached.class, B.class, SubClass.class} )
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
|||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hibernate.cfg.AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY;
|
||||
import static org.hibernate.cfg.AvailableSettings.GENERATE_STATISTICS;
|
||||
import static org.hibernate.cfg.AvailableSettings.USE_SECOND_LEVEL_CACHE;
|
||||
import static org.hibernate.testing.cache.CachingRegionFactory.DEFAULT_ACCESSTYPE;
|
||||
|
@ -29,7 +30,8 @@ import static org.junit.Assert.assertNull;
|
|||
settings = {
|
||||
@Setting( name = USE_SECOND_LEVEL_CACHE, value = "true" ),
|
||||
@Setting( name = DEFAULT_ACCESSTYPE, value = "nonstrict-read-write" ),
|
||||
@Setting( name = GENERATE_STATISTICS, value = "true" )
|
||||
@Setting( name = GENERATE_STATISTICS, value = "true" ),
|
||||
@Setting( name = ALLOW_REFRESH_DETACHED_ENTITY, value = "true" )
|
||||
}
|
||||
)
|
||||
@DomainModel( annotatedClasses = {A.class, Another.class, AllCached.class, B.class, SubClass.class} )
|
||||
|
|
|
@ -8,12 +8,15 @@ package org.hibernate.orm.test.orphan;
|
|||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.internal.util.SerializationHelper;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -28,6 +31,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
xmlMappings = "org/hibernate/orm/test/orphan/Product.hbm.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class OrphanTest {
|
||||
|
||||
@AfterEach
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.test.pc;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Fábio Takeo Ueno
|
||||
*/
|
||||
public class CascadeLockTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Person.class,
|
||||
Phone.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lockTest() {
|
||||
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||
Person person = new Person();
|
||||
person.setId(1L);
|
||||
person.setName("John Doe");
|
||||
|
||||
Phone phone = new Phone();
|
||||
phone.setId(1L);
|
||||
phone.setNumber("123-456-7890");
|
||||
|
||||
person.addPhone(phone);
|
||||
entityManager.persist(person);
|
||||
});
|
||||
|
||||
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||
|
||||
//tag::pc-cascade-lock-example[]
|
||||
Person person = entityManager.find(Person.class, 1L);
|
||||
assertEquals(1, person.getPhones().size());
|
||||
Phone phone = person.getPhones().get(0);
|
||||
|
||||
assertTrue(entityManager.contains(person));
|
||||
assertTrue(entityManager.contains(phone));
|
||||
|
||||
entityManager.detach(person);
|
||||
|
||||
assertFalse(entityManager.contains(person));
|
||||
assertFalse(entityManager.contains(phone));
|
||||
|
||||
entityManager.unwrap(Session.class)
|
||||
.lock(person, new LockOptions(LockMode.NONE));
|
||||
|
||||
assertTrue(entityManager.contains(person));
|
||||
assertTrue(entityManager.contains(phone));
|
||||
//end::pc-cascade-lock-example[]
|
||||
});
|
||||
}
|
||||
}
|
|
@ -252,34 +252,6 @@ public class PersistenceContextTest extends BaseEntityManagerFunctionalTestCase
|
|||
//end::pc-refresh-native-example[]
|
||||
});
|
||||
|
||||
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||
Session session = entityManager.unwrap(Session.class);
|
||||
Long personId = _personId;
|
||||
|
||||
//tag::pc-detach-reattach-lock-example[]
|
||||
Person person = session.byId(Person.class).load(personId);
|
||||
//Clear the Session so the person entity becomes detached
|
||||
session.clear();
|
||||
person.setName("Mr. John Doe");
|
||||
|
||||
session.lock(person, LockMode.NONE);
|
||||
//end::pc-detach-reattach-lock-example[]
|
||||
});
|
||||
|
||||
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||
Session session = entityManager.unwrap(Session.class);
|
||||
Long personId = _personId;
|
||||
|
||||
//tag::pc-detach-reattach-saveOrUpdate-example[]
|
||||
Person person = session.byId(Person.class).load(personId);
|
||||
//Clear the Session so the person entity becomes detached
|
||||
session.clear();
|
||||
person.setName("Mr. John Doe");
|
||||
|
||||
session.merge(person);
|
||||
//end::pc-detach-reattach-saveOrUpdate-example[]
|
||||
});
|
||||
|
||||
doInJPA(this::entityManagerFactory, entityManager -> {
|
||||
Session session = entityManager.unwrap(Session.class);
|
||||
Long personId = _personId;
|
||||
|
|
|
@ -14,13 +14,16 @@ import org.hibernate.Session;
|
|||
import org.hibernate.Transaction;
|
||||
import org.hibernate.TransientObjectException;
|
||||
import org.hibernate.UnresolvableObjectException;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.FailureExpected;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
@ -42,6 +45,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
"org/hibernate/orm/test/readonly/TextHolder.hbm.xml"
|
||||
}
|
||||
)
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class ReadOnlyProxyTest extends AbstractReadOnlyTest {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -15,11 +15,14 @@ import org.hibernate.ScrollMode;
|
|||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.query.Query;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -38,6 +41,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
"org/hibernate/orm/test/readonly/TextHolder.hbm.xml"
|
||||
}
|
||||
)
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class ReadOnlySessionTest extends AbstractReadOnlyTest {
|
||||
|
||||
@AfterEach
|
||||
|
|
|
@ -15,8 +15,11 @@ import org.hibernate.ScrollableResults;
|
|||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
@ -35,6 +38,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
"org/hibernate/orm/test/readonly/TextHolder.hbm.xml"
|
||||
}
|
||||
)
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class ReadOnlyTest extends AbstractReadOnlyTest {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.orm.test.refresh;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public class Customer {
|
||||
private long id;
|
||||
|
||||
public long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -6,12 +6,15 @@
|
|||
*/
|
||||
package org.hibernate.orm.test.refresh;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.orm.test.jpa.refresh.TestEntity;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -24,6 +27,7 @@ import org.junit.jupiter.api.Test;
|
|||
annotatedClasses = TestEntity.class
|
||||
)
|
||||
@SessionFactory
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class RefreshDetachedInstanceWhenIsAllowedTest {
|
||||
private TestEntity testEntity;
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ public class RefreshTest {
|
|||
@Test
|
||||
public void testRefreshWithNullId(SessionFactoryScope scope) {
|
||||
Assertions.assertThrows(
|
||||
TransientObjectException.class,
|
||||
IllegalArgumentException.class,
|
||||
() -> {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.orm.test.refresh;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-11217")
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/refresh/Customer.hbm.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
public class RefreshUsingEntityNameTest {
|
||||
private Customer customer;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp(SessionFactoryScope scope) {
|
||||
customer = new Customer();
|
||||
scope.inTransaction(
|
||||
session ->
|
||||
session.persist( "CustomName", customer )
|
||||
);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session ->
|
||||
session.createQuery( "delete from CustomName" ).executeUpdate()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshUsingEntityName(SessionFactoryScope scope) {
|
||||
scope.inSession(
|
||||
session ->
|
||||
session.refresh( customer )
|
||||
);
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ import jakarta.persistence.ManyToOne;
|
|||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.proxy.AbstractLazyInitializer;
|
||||
|
||||
|
@ -23,6 +24,7 @@ import org.hibernate.testing.logger.Triggerable;
|
|||
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Jpa;
|
||||
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.Rule;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -36,10 +38,9 @@ import static org.junit.Assert.fail;
|
|||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
@Jpa(annotatedClasses = {
|
||||
AssociateEntityWithTwoSessionsTest.Location.class,
|
||||
AssociateEntityWithTwoSessionsTest.Event.class
|
||||
})
|
||||
@Jpa(annotatedClasses = {AssociateEntityWithTwoSessionsTest.Location.class,
|
||||
AssociateEntityWithTwoSessionsTest.Event.class},
|
||||
properties = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class AssociateEntityWithTwoSessionsTest {
|
||||
|
||||
@Rule
|
||||
|
@ -65,8 +66,8 @@ public class AssociateEntityWithTwoSessionsTest {
|
|||
triggerable.reset();
|
||||
|
||||
scope.inTransaction( entityManager -> {
|
||||
Event event1 = entityManager.find( Event.class, event.id );
|
||||
Location location1 = event1.getLocation();
|
||||
Event e = entityManager.find( Event.class, event.id );
|
||||
Location location1 = e.getLocation();
|
||||
|
||||
try {
|
||||
scope.inTransaction( _entityManager -> {
|
||||
|
|
|
@ -12,9 +12,10 @@ import org.hibernate.LockMode;
|
|||
import org.hibernate.annotations.Filter;
|
||||
import org.hibernate.annotations.FilterDef;
|
||||
import org.hibernate.annotations.ParamDef;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.sql.ast.spi.ParameterMarkerStrategy;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
|
||||
import org.hibernate.testing.jdbc.SQLStatementInspector;
|
||||
|
@ -47,7 +48,7 @@ import static org.hibernate.internal.util.StringHelper.*;
|
|||
@ServiceRegistry( services = @ServiceRegistry.Service(
|
||||
role = ParameterMarkerStrategy.class,
|
||||
impl = ParameterMarkerStrategyTests.ParameterMarkerStrategyImpl.class
|
||||
) )
|
||||
), settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true") )
|
||||
@DomainModel( annotatedClasses = {
|
||||
EntityOfBasics.class,
|
||||
ParameterMarkerStrategyTests.EntityWithFilters.class,
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE hibernate-mapping PUBLIC
|
||||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping>
|
||||
<class name="org.hibernate.orm.test.refresh.Customer"
|
||||
entity-name="CustomName"
|
||||
lazy="false">
|
||||
|
||||
<id name="id"/>
|
||||
</class>
|
||||
</hibernate-mapping>
|
Loading…
Reference in New Issue