HHH-11147 - Allow enhanced entities to be returned in a completely uninitialized state
(cherry picked from commit 94c49aaaa6
)
This commit is contained in:
parent
6d2c4aad29
commit
0a17f5ba6d
|
@ -6,11 +6,13 @@
|
|||
*/
|
||||
package org.hibernate.bytecode.enhance.spi.interceptor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.bytecode.BytecodeLogger;
|
||||
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
|
||||
|
@ -22,6 +24,7 @@ import org.hibernate.internal.util.collections.ArrayHelper;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -213,18 +216,31 @@ public class EnhancementAsProxyLazinessInterceptor extends AbstractLazyLoadInter
|
|||
}
|
||||
|
||||
if ( identifierAttributeNames.contains( attributeName ) ) {
|
||||
EnhancementHelper.performWork(
|
||||
this,
|
||||
(session, isTempSession) -> session.getFactory()
|
||||
.getMetamodel()
|
||||
.entityPersister( getEntityName() )
|
||||
.getEntityTuplizer()
|
||||
.getPropertyValue( target, attributeName ),
|
||||
getEntityName(),
|
||||
attributeName
|
||||
// it is illegal for the identifier value to be changed. Normally Hibernate
|
||||
// validates this during flush. However, here it is dangerous to just allow the
|
||||
// new value to be set and continue on waiting for the flush for validation
|
||||
// because this interceptor manages the entity's entry in the PC itself. So
|
||||
// just do the check here up-front
|
||||
final boolean changed;
|
||||
if ( nonAggregatedCidMapper == null ) {
|
||||
changed = ! entityKey.getPersister().getIdentifierType().isEqual( oldValue, newValue );
|
||||
}
|
||||
else {
|
||||
final int subAttrIndex = nonAggregatedCidMapper.getPropertyIndex( attributeName );
|
||||
final Type subAttrType = nonAggregatedCidMapper.getSubtypes()[subAttrIndex];
|
||||
changed = ! subAttrType.isEqual( oldValue, newValue );
|
||||
}
|
||||
|
||||
if ( changed ) {
|
||||
throw new HibernateException(
|
||||
"identifier of an instance of " + entityKey.getEntityName() + " was altered from " + oldValue + " to " + newValue
|
||||
);
|
||||
}
|
||||
|
||||
// otherwise, setId has been called but passing in the same value - just pass it through
|
||||
return newValue;
|
||||
}
|
||||
|
||||
if ( ! inLineDirtyChecking ) {
|
||||
// we need to force-initialize the proxy - the fetch group to which the `attributeName` belongs
|
||||
try {
|
||||
|
|
|
@ -74,6 +74,10 @@ public final class EntityKey implements Serializable {
|
|||
return persister.getEntityName();
|
||||
}
|
||||
|
||||
public EntityPersister getPersister() {
|
||||
return persister;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if ( this == other ) {
|
||||
|
|
|
@ -95,13 +95,11 @@ public class SetIdentifierOnAEnhancedProxyTest extends BaseNonConfigCoreFunction
|
|||
|
||||
loadedChild.setId( lastChildID );
|
||||
|
||||
// ^ should have triggered "base fetch group" initialization which would mean a SQL select
|
||||
assertEquals( 1, stats.getPrepareStatementCount() );
|
||||
assertEquals( 0, stats.getPrepareStatementCount() );
|
||||
|
||||
// check that the `#setName` "persisted"
|
||||
assertThat( loadedChild.getId(), is( lastChildID ) );
|
||||
assertEquals( 1, stats.getPrepareStatementCount() );
|
||||
|
||||
assertEquals( 0, stats.getPrepareStatementCount() );
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -114,7 +112,6 @@ public class SetIdentifierOnAEnhancedProxyTest extends BaseNonConfigCoreFunction
|
|||
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test(expected = PersistenceException.class)
|
||||
public void updateIdTest() {
|
||||
final Statistics stats = sessionFactory().getStatistics();
|
||||
|
@ -133,13 +130,11 @@ public class SetIdentifierOnAEnhancedProxyTest extends BaseNonConfigCoreFunction
|
|||
|
||||
loadedChild.setId( updatedId );
|
||||
|
||||
// ^ should have triggered "base fetch group" initialization which would mean a SQL select
|
||||
assertEquals( 1, stats.getPrepareStatementCount() );
|
||||
assertEquals( 0, stats.getPrepareStatementCount() );
|
||||
|
||||
// check that the `#setName` "persisted"
|
||||
assertThat( loadedChild.getId(), is( updatedId ) );
|
||||
assertEquals( 1, stats.getPrepareStatementCount() );
|
||||
|
||||
assertEquals( 0, stats.getPrepareStatementCount() );
|
||||
}
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue