mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-16 16:15:06 +00:00
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 SessionFactoryOptionsBuilder(StandardServiceRegistry serviceRegistry, Boo
|
||||
this.allowRefreshDetachedEntity = configurationService.getSetting(
|
||||
ALLOW_REFRESH_DETACHED_ENTITY,
|
||||
BOOLEAN,
|
||||
true
|
||||
false
|
||||
);
|
||||
|
||||
this.flushBeforeCompletionEnabled = configurationService.getSetting( FLUSH_BEFORE_COMPLETION, BOOLEAN, true );
|
||||
|
@ -659,6 +659,7 @@ private void fireLock(Object object, LockOptions options) {
|
||||
|
||||
private void fireLock(LockEvent event) {
|
||||
checkOpen();
|
||||
checkEntityManaged( event.getEntityName(), event.getObject() );
|
||||
pulseTransactionCoordinator();
|
||||
fastSessionServices.eventListenerGroup_LOCK
|
||||
.fireEventOnEachListener( event, LockEventListener::onLock );
|
||||
@ -1163,18 +1164,7 @@ public void refresh(String entityName, Object object, RefreshContext refreshedAl
|
||||
|
||||
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 @@ private void fireRefresh(final RefreshEvent event) {
|
||||
|
||||
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 @@ private void fireRefresh(final RefreshContext refreshedAlready, final RefreshEve
|
||||
}
|
||||
}
|
||||
|
||||
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 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 EntityInitializerData(EntityInitializerImpl initializer, RowProcessingSta
|
||||
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 EntityInitializerData(EntityInitializerImpl initializer, RowProcessingSta
|
||||
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 EntityInitializerData(EntityInitializerData original) {
|
||||
}
|
||||
}
|
||||
|
||||
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 EntityInitializerImpl(
|
||||
: 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 EntityInitializerImpl(
|
||||
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 EntityInitializerImpl(
|
||||
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 EntityInitializerImpl(
|
||||
}
|
||||
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 EntityInitializerImpl(
|
||||
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 EntityInitializerImpl(
|
||||
|
||||
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 @@ protected void resolveKey(EntityInitializerData data, boolean entityKeyOnly) {
|
||||
}
|
||||
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 boolean isResultInitializer() {
|
||||
}
|
||||
|
||||
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 Object getTargetInstance(EntityInitializerData data) {
|
||||
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 @@ protected void initializeAttributeType(Type[] attributeTypes, EntityPersister en
|
||||
@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 @@ protected void initializeAttributeType(Type[] attributeTypes, EntityPersister en
|
||||
}
|
||||
|
||||
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 void resolveInstance(Object instance, EntityInitializerData data) {
|
||||
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 @@ protected void upgradeLockMode(EntityInitializerData data) {
|
||||
|
||||
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 @@
|
||||
|
||||
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 @@
|
||||
)
|
||||
@SessionFactory
|
||||
@BytecodeEnhanced
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class UnexpectedDeleteTest2 {
|
||||
|
||||
private Bar myBar;
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
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.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 @@
|
||||
@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 @@
|
||||
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.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 @@
|
||||
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.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 @@
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class RefreshTest {
|
||||
|
||||
private JobBatch batch;
|
||||
|
@ -8,12 +8,15 @@
|
||||
|
||||
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 @@
|
||||
)
|
||||
)
|
||||
@SessionFactory
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.ALLOW_REFRESH_DETACHED_ENTITY, value = "true"))
|
||||
public class BackrefCompositeMapKeyTest {
|
||||
|
||||
@Test
|
||||
|
@ -301,7 +301,6 @@ public void testPaginationWithFormulaSubquery() {
|
||||
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 @@ protected void applyMetadataBuilder(MetadataBuilder metadataBuilder) {
|
||||
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 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 @@
|
||||
* @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 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 @@
|
||||
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.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 @@
|
||||
/**
|
||||
* @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 @@
|
||||
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.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 @@
|
||||
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 @@
|
||||
|
||||
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 @@
|
||||
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 void test() {
|
||||
//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.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 @@
|
||||
"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.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 @@
|
||||
"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.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 @@
|
||||
"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 @@
|
||||
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 void testIt(SessionFactoryScope scope) {
|
||||
@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 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.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 @@
|
||||
/**
|
||||
* @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 void test(EntityManagerFactoryScope scope) {
|
||||
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.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 @@
|
||||
@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…
x
Reference in New Issue
Block a user