HHH-15858 Improvements in Session casting

This commit is contained in:
Sanne Grinovero 2022-12-13 15:45:16 +00:00 committed by Sanne Grinovero
parent 2c3ac612db
commit a7274875ca
10 changed files with 63 additions and 16 deletions

View File

@ -276,7 +276,7 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
session session
.getFactory() .getFactory()
.getCustomEntityDirtinessStrategy() .getCustomEntityDirtinessStrategy()
.resetDirty( entity, persister, (Session) session ); .resetDirty( entity, persister, session.asSessionImplementor() );
} }
private static void clearDirtyAttributes(final SelfDirtinessTracker entity) { private static void clearDirtyAttributes(final SelfDirtinessTracker entity) {
@ -370,8 +370,9 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
final CustomEntityDirtinessStrategy customEntityDirtinessStrategy = final CustomEntityDirtinessStrategy customEntityDirtinessStrategy =
getPersistenceContext().getSession().getFactory().getCustomEntityDirtinessStrategy(); getPersistenceContext().getSession().getFactory().getCustomEntityDirtinessStrategy();
if ( customEntityDirtinessStrategy.canDirtyCheck( entity, getPersister(), (Session) getPersistenceContext().getSession() ) ) { final Session session = getPersistenceContext().getSession().asSessionImplementor();
return ! customEntityDirtinessStrategy.isDirty( entity, getPersister(), (Session) getPersistenceContext().getSession() ); if ( customEntityDirtinessStrategy.canDirtyCheck( entity, getPersister(), session ) ) {
return ! customEntityDirtinessStrategy.isDirty( entity, getPersister(), session );
} }
if ( getPersister().hasMutableProperties() ) { if ( getPersister().hasMutableProperties() ) {

View File

@ -112,4 +112,15 @@ public interface SessionImplementor extends Session, SharedSessionContractImplem
*/ */
@Deprecated @Deprecated
void removeOrphanBeforeUpdates(String entityName, Object child); void removeOrphanBeforeUpdates(String entityName, Object child);
@Override
default SessionImplementor asSessionImplementor() {
return this;
}
@Override
default boolean isSessionImplementor() {
return true;
}
} }

View File

@ -15,6 +15,7 @@ import org.hibernate.CacheMode;
import org.hibernate.FlushMode; import org.hibernate.FlushMode;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.Interceptor; import org.hibernate.Interceptor;
import org.hibernate.StatelessSession;
import org.hibernate.event.spi.EventSource; import org.hibernate.event.spi.EventSource;
import org.hibernate.query.Query; import org.hibernate.query.Query;
import org.hibernate.SharedSessionContract; import org.hibernate.SharedSessionContract;
@ -440,4 +441,30 @@ public interface SharedSessionContractImplementor
*/ */
void afterOperation(boolean success); void afterOperation(boolean success);
/**
* If this can be casted to a @{@link SessionImplementor},
* you'll get this returned after an efficient cast.
* @throws ClassCastException if this is not compatible!
*/
default SessionImplementor asSessionImplementor() {
throw new ClassCastException();
}
default boolean isSessionImplementor() {
return false;
}
/**
* If this can be casted to a @{@link StatelessSession},
* you'll get this returned after an efficient cast.
* @throws ClassCastException if this is not compatible!
*/
default StatelessSession asStatelessSession() {
throw new ClassCastException();
}
default boolean isStatelessSession() {
return false;
}
} }

View File

@ -92,7 +92,7 @@ public class CurrentTimestampGeneration implements InMemoryGenerator, InDatabase
@Override @Override
public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) { public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) {
return generator.generateValue( (Session) session, owner, currentValue ); return generator.generateValue( session.asSessionImplementor(), owner, currentValue );
} }
@Override @Override

View File

@ -90,7 +90,7 @@ public class SourceGeneration implements InMemoryGenerator {
@Override @Override
public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) { public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) {
return valueGenerator.generateValue( (Session) session, owner, currentValue ); return valueGenerator.generateValue( session.asSessionImplementor(), owner, currentValue );
} }
public Object generateValue(Session session, Object owner) { public Object generateValue(Session session, Object owner) {

View File

@ -10,13 +10,10 @@ import java.util.Properties;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.hibernate.TransientObjectException; import org.hibernate.TransientObjectException;
import org.hibernate.engine.internal.ForeignKeys;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.factory.spi.StandardGenerator; import org.hibernate.id.factory.spi.StandardGenerator;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.loader.PropertyPath;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.EntityType; import org.hibernate.type.EntityType;
@ -118,18 +115,18 @@ public class ForeignGenerator implements IdentifierGenerator, StandardGenerator
associatedEntityName associatedEntityName
); );
} }
if ( sessionImplementor instanceof Session ) { if ( sessionImplementor.isSessionImplementor() ) {
id = ((Session) sessionImplementor).save( associatedEntityName, associatedObject ); id = sessionImplementor.asSessionImplementor().save( associatedEntityName, associatedObject );
} }
else if ( sessionImplementor instanceof StatelessSession ) { else if ( sessionImplementor.isStatelessSession() ) {
id = ((StatelessSession) sessionImplementor).insert( associatedEntityName, associatedObject ); id = sessionImplementor.asStatelessSession().insert( associatedEntityName, associatedObject );
} }
else { else {
throw new IdentifierGenerationException("sessionImplementor is neither Session nor StatelessSession"); throw new IdentifierGenerationException("sessionImplementor is neither Session nor StatelessSession");
} }
} }
if ( sessionImplementor instanceof Session && ((Session) sessionImplementor).contains( entityName, object ) ) { if ( sessionImplementor.isSessionImplementor() && sessionImplementor.asSessionImplementor().contains( entityName, object ) ) {
//abort the save (the object is already saved by a circular cascade) //abort the save (the object is already saved by a circular cascade)
return SHORT_CIRCUIT_INDICATOR; return SHORT_CIRCUIT_INDICATOR;
//throw new IdentifierGenerationException("save associated object first, or disable cascade for inverse association"); //throw new IdentifierGenerationException("save associated object first, or disable cascade for inverse association");

View File

@ -725,4 +725,15 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
private LockMode getNullSafeLockMode(LockMode lockMode) { private LockMode getNullSafeLockMode(LockMode lockMode) {
return lockMode == null ? LockMode.NONE : lockMode; return lockMode == null ? LockMode.NONE : lockMode;
} }
@Override
public StatelessSession asStatelessSession() {
return this;
}
@Override
public boolean isStatelessSession() {
return true;
}
} }

View File

@ -119,7 +119,7 @@ public class DeferredResultSetAccess extends AbstractResultSetAccess {
executionContext.getCallback().registerAfterLoadAction( executionContext.getCallback().registerAfterLoadAction(
(session, entity, persister) -> (session, entity, persister) ->
( (SessionImplementor) session ).lock( session.asSessionImplementor().lock(
persister.getEntityName(), persister.getEntityName(),
entity, entity,
lockOptionsToUse lockOptionsToUse

View File

@ -59,7 +59,7 @@ public interface ValueGeneration extends InMemoryGenerator, InDatabaseGenerator
@Override @Override
default Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) { default Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) {
return getValueGenerator().generateValue( (Session) session, owner, currentValue ); return getValueGenerator().generateValue( session.asSessionImplementor(), owner, currentValue );
} }
/** /**

View File

@ -52,6 +52,6 @@ public class VmValueGeneration implements InMemoryGenerator {
@Override @Override
public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) { public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) {
return generator.generateValue( (Session) session, owner, currentValue ); return generator.generateValue( session.asSessionImplementor(), owner, currentValue );
} }
} }