HHH-14464 Expose useful things to enable cleanup of HR code

- expose useful static-y methods in AbstractEntityPersister
- add methods to OptimisticLockStyle to reduce verbosity
- add a useful method to ValueGeneration
This commit is contained in:
Gavin King 2021-02-23 10:26:55 +01:00 committed by Sanne Grinovero
parent af786b327b
commit ef6e1b8315
5 changed files with 58 additions and 46 deletions

View File

@ -39,6 +39,26 @@ public int getOldCode() {
return oldCode; return oldCode;
} }
public boolean isAllOrDirty() {
return isAll() || isDirty();
}
public boolean isAll() {
return this == ALL;
}
public boolean isDirty() {
return this == DIRTY;
}
public boolean isVersion() {
return this == VERSION;
}
public boolean isNone() {
return this == NONE;
}
/** /**
* Given an old code (one of the int constants from Cascade), interpret it as one of the new enums. * Given an old code (one of the int constants from Cascade), interpret it as one of the new enums.
* *

View File

@ -1375,8 +1375,8 @@ protected boolean initializeLazyProperty(
} }
public boolean isBatchable() { public boolean isBatchable() {
return optimisticLockStyle() == OptimisticLockStyle.NONE return optimisticLockStyle().isNone()
|| ( !isVersioned() && optimisticLockStyle() == OptimisticLockStyle.VERSION ) || !isVersioned() && optimisticLockStyle().isVersion()
|| getFactory().getSessionFactoryOptions().isJdbcBatchVersionedData(); || getFactory().getSessionFactoryOptions().isJdbcBatchVersionedData();
} }
@ -1746,14 +1746,13 @@ private String generateGeneratedValuesSelectString(final GenerationTiming genera
// rather than trying to handle the individual generated portions. // rather than trying to handle the individual generated portions.
String selectClause = concretePropertySelectFragment( String selectClause = concretePropertySelectFragment(
getRootAlias(), getRootAlias(),
new InclusionChecker() { propertyNumber -> {
@Override
public boolean includeProperty(int propertyNumber) {
final InDatabaseValueGenerationStrategy generationStrategy final InDatabaseValueGenerationStrategy generationStrategy
= entityMetamodel.getInDatabaseValueGenerationStrategies()[propertyNumber]; = entityMetamodel.getInDatabaseValueGenerationStrategies()[propertyNumber];
GenerationTiming timing = generationStrategy.getGenerationTiming();
return generationStrategy != null return generationStrategy != null
&& timingsMatch( generationStrategy.getGenerationTiming(), generationTimingToMatch ); && (generationTimingToMatch == GenerationTiming.INSERT && timing.includesInsert()
} || generationTimingToMatch == GenerationTiming.ALWAYS && timing.includesUpdate());
} }
); );
selectClause = selectClause.substring( 2 ); selectClause = selectClause.substring( 2 );
@ -1781,11 +1780,7 @@ protected interface InclusionChecker {
protected String concretePropertySelectFragment(String alias, final boolean[] includeProperty) { protected String concretePropertySelectFragment(String alias, final boolean[] includeProperty) {
return concretePropertySelectFragment( return concretePropertySelectFragment(
alias, alias,
new InclusionChecker() { propertyNumber -> includeProperty[propertyNumber]
public boolean includeProperty(int propertyNumber) {
return includeProperty[propertyNumber];
}
}
); );
} }
@ -2715,7 +2710,7 @@ public String generateUpdateString(
update.addPrimaryKeyColumns( getKeyColumns( j ) ); update.addPrimaryKeyColumns( getKeyColumns( j ) );
} }
if ( j == 0 && isVersioned() && entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.VERSION ) { if ( j == 0 && isVersioned() && entityMetamodel.getOptimisticLockStyle().isVersion() ) {
// this is the root (versioned) table, and we are using version-based // this is the root (versioned) table, and we are using version-based
// optimistic locking; if we are not updating the version, also don't // optimistic locking; if we are not updating the version, also don't
// check it (unless this is a "generated" version column)! // check it (unless this is a "generated" version column)!
@ -2727,12 +2722,11 @@ public String generateUpdateString(
else if ( isAllOrDirtyOptLocking() && oldFields != null ) { else if ( isAllOrDirtyOptLocking() && oldFields != null ) {
// we are using "all" or "dirty" property-based optimistic locking // we are using "all" or "dirty" property-based optimistic locking
boolean[] includeInWhere = entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.ALL boolean[] includeInWhere = entityMetamodel.getOptimisticLockStyle().isAll()
?
getPropertyUpdateability()
//optimistic-lock="all", include all updatable properties //optimistic-lock="all", include all updatable properties
: ? getPropertyUpdateability()
includeProperty; //optimistic-lock="dirty", include all properties we are updating this time //optimistic-lock="dirty", include all properties we are updating this time
: includeProperty;
boolean[] versionability = getPropertyVersionability(); boolean[] versionability = getPropertyVersionability();
Type[] types = getPropertyTypes(); Type[] types = getPropertyTypes();
@ -3459,14 +3453,14 @@ public boolean update(
); );
// Write any appropriate versioning conditional parameters // Write any appropriate versioning conditional parameters
if ( useVersion && entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.VERSION ) { if ( useVersion && entityMetamodel.getOptimisticLockStyle().isVersion()) {
if ( checkVersion( includeProperty ) ) { if ( checkVersion( includeProperty ) ) {
getVersionType().nullSafeSet( update, oldVersion, index, session ); getVersionType().nullSafeSet( update, oldVersion, index, session );
} }
} }
else if ( isAllOrDirtyOptLocking() && oldFields != null ) { else if ( isAllOrDirtyOptLocking() && oldFields != null ) {
boolean[] versionability = getPropertyVersionability(); //TODO: is this really necessary???? boolean[] versionability = getPropertyVersionability(); //TODO: is this really necessary????
boolean[] includeOldField = entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.ALL boolean[] includeOldField = entityMetamodel.getOptimisticLockStyle().isAll()
? getPropertyUpdateability() ? getPropertyUpdateability()
: includeProperty; : includeProperty;
Type[] types = getPropertyTypes(); Type[] types = getPropertyTypes();
@ -3882,8 +3876,7 @@ public void delete(Serializable id, Object version, Object object, SharedSession
} }
protected boolean isAllOrDirtyOptLocking() { protected boolean isAllOrDirtyOptLocking() {
return entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.DIRTY return entityMetamodel.getOptimisticLockStyle().isAllOrDirty();
|| entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.ALL;
} }
protected String[] generateSQLDeleteStrings(Object[] loadedState) { protected String[] generateSQLDeleteStrings(Object[] loadedState) {
@ -5367,12 +5360,11 @@ rs, getPropertyAliases(
} }
private boolean isValueGenerationRequired(NonIdentifierAttribute attribute, GenerationTiming matchTiming) { public static boolean isValueGenerationRequired(NonIdentifierAttribute attribute, GenerationTiming matchTiming) {
if ( attribute.getType() instanceof ComponentType ) { if ( attribute.getType() instanceof ComponentType) {
final ComponentType type = (ComponentType) attribute.getType(); final ComponentType type = (ComponentType) attribute.getType();
final ValueGeneration[] propertyValueGenerationStrategies = type.getPropertyValueGenerationStrategies(); for ( ValueGeneration valueGenerationStrategy : type.getPropertyValueGenerationStrategies() ) {
for ( ValueGeneration propertyValueGenerationStrategie : propertyValueGenerationStrategies ) { if ( isReadRequired( valueGenerationStrategy, matchTiming ) ) {
if ( isReadRequired( propertyValueGenerationStrategie, matchTiming ) ) {
return true; return true;
} }
} }
@ -5386,16 +5378,10 @@ private boolean isValueGenerationRequired(NonIdentifierAttribute attribute, Gene
/** /**
* Whether the given value generation strategy requires to read the value from the database or not. * Whether the given value generation strategy requires to read the value from the database or not.
*/ */
private boolean isReadRequired(ValueGeneration valueGeneration, GenerationTiming matchTiming) { private static boolean isReadRequired(ValueGeneration valueGeneration, GenerationTiming matchTiming) {
return valueGeneration != null && return valueGeneration != null
valueGeneration.getValueGenerator() == null && && valueGeneration.getValueGenerator() == null
timingsMatch( valueGeneration.getGenerationTiming(), matchTiming ); && valueGeneration.timingMatches( matchTiming );
}
private boolean timingsMatch(GenerationTiming timing, GenerationTiming matchTiming) {
return
( matchTiming == GenerationTiming.INSERT && timing.includesInsert() ) ||
( matchTiming == GenerationTiming.ALWAYS && timing.includesUpdate() );
} }
public String getIdentifierPropertyName() { public String getIdentifierPropertyName() {
@ -5576,7 +5562,7 @@ public Serializable loadEntityIdByNaturalId(
} }
} }
private boolean[] determineValueNullness(Object[] naturalIdValues) { public static boolean[] determineValueNullness(Object[] naturalIdValues) {
boolean[] nullness = new boolean[naturalIdValues.length]; boolean[] nullness = new boolean[naturalIdValues.length];
for ( int i = 0; i < naturalIdValues.length; i++ ) { for ( int i = 0; i < naturalIdValues.length; i++ ) {
nullness[i] = naturalIdValues[i] == null; nullness[i] = naturalIdValues[i] == null;

View File

@ -13,7 +13,6 @@
import org.hibernate.boot.model.relational.Database; import org.hibernate.boot.model.relational.Database;
import org.hibernate.cache.spi.access.EntityDataAccess; import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.NaturalIdDataAccess; import org.hibernate.cache.spi.access.NaturalIdDataAccess;
import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle; import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -200,7 +199,7 @@ else if ( persistentClass.isDiscriminatorValueNotNull() ) {
discriminatorSQLString = null; discriminatorSQLString = null;
} }
if ( optimisticLockStyle() == OptimisticLockStyle.ALL || optimisticLockStyle() == OptimisticLockStyle.DIRTY ) { if ( optimisticLockStyle().isAllOrDirty() ) {
throw new MappingException( "optimistic-lock=all|dirty not supported for joined-subclass mappings [" + getEntityName() + "]" ); throw new MappingException( "optimistic-lock=all|dirty not supported for joined-subclass mappings [" + getEntityName() + "]" );
} }

View File

@ -53,4 +53,13 @@ public interface ValueGeneration extends Serializable {
* @return The column value to be used in the SQL. * @return The column value to be used in the SQL.
*/ */
public String getDatabaseGeneratedReferencedColumnValue(); public String getDatabaseGeneratedReferencedColumnValue();
/**
* Does this value generation occur with the given timing?
*/
default boolean timingMatches(GenerationTiming timing) {
GenerationTiming generationTiming = getGenerationTiming();
return timing == GenerationTiming.INSERT && generationTiming.includesInsert()
|| timing == GenerationTiming.ALWAYS && generationTiming.includesUpdate();
}
} }

View File

@ -387,9 +387,7 @@ else if ( timing == GenerationTiming.ALWAYS ) {
hasSubclasses = persistentClass.hasSubclasses(); hasSubclasses = persistentClass.hasSubclasses();
optimisticLockStyle = persistentClass.getOptimisticLockStyle(); optimisticLockStyle = persistentClass.getOptimisticLockStyle();
final boolean isAllOrDirty = final boolean isAllOrDirty = optimisticLockStyle.isAllOrDirty();
optimisticLockStyle == OptimisticLockStyle.ALL
|| optimisticLockStyle == OptimisticLockStyle.DIRTY;
if ( isAllOrDirty && !dynamicUpdate ) { if ( isAllOrDirty && !dynamicUpdate ) {
throw new MappingException( "optimistic-lock=all|dirty requires dynamic-update=\"true\": " + name ); throw new MappingException( "optimistic-lock=all|dirty requires dynamic-update=\"true\": " + name );
} }