From e38df7ed593af7dc124d10c30eea5389c76af124 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Tue, 23 Feb 2021 10:26:55 +0100 Subject: [PATCH] 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 --- .../hibernate/engine/OptimisticLockStyle.java | 20 ++++++ .../entity/AbstractEntityPersister.java | 68 ++++++++----------- .../entity/JoinedSubclassEntityPersister.java | 3 +- .../org/hibernate/tuple/ValueGeneration.java | 9 +++ .../tuple/entity/EntityMetamodel.java | 4 +- 5 files changed, 58 insertions(+), 46 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/engine/OptimisticLockStyle.java b/hibernate-core/src/main/java/org/hibernate/engine/OptimisticLockStyle.java index aca8aaac16..8398770a81 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/OptimisticLockStyle.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/OptimisticLockStyle.java @@ -39,6 +39,26 @@ public int getOldCode() { 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. * diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index fcffca53e2..ebc334da44 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -1386,8 +1386,8 @@ protected boolean initializeLazyProperty( } public boolean isBatchable() { - return optimisticLockStyle() == OptimisticLockStyle.NONE - || ( !isVersioned() && optimisticLockStyle() == OptimisticLockStyle.VERSION ) + return optimisticLockStyle().isNone() + || !isVersioned() && optimisticLockStyle().isVersion() || getFactory().getSessionFactoryOptions().isJdbcBatchVersionedData(); } @@ -1757,14 +1757,13 @@ private String generateGeneratedValuesSelectString(final GenerationTiming genera // rather than trying to handle the individual generated portions. String selectClause = concretePropertySelectFragment( getRootAlias(), - new InclusionChecker() { - @Override - public boolean includeProperty(int propertyNumber) { - final InDatabaseValueGenerationStrategy generationStrategy - = entityMetamodel.getInDatabaseValueGenerationStrategies()[propertyNumber]; - return generationStrategy != null - && timingsMatch( generationStrategy.getGenerationTiming(), generationTimingToMatch ); - } + propertyNumber -> { + final InDatabaseValueGenerationStrategy generationStrategy + = entityMetamodel.getInDatabaseValueGenerationStrategies()[propertyNumber]; + GenerationTiming timing = generationStrategy.getGenerationTiming(); + return generationStrategy != null + && (generationTimingToMatch == GenerationTiming.INSERT && timing.includesInsert() + || generationTimingToMatch == GenerationTiming.ALWAYS && timing.includesUpdate()); } ); selectClause = selectClause.substring( 2 ); @@ -1792,11 +1791,7 @@ protected interface InclusionChecker { protected String concretePropertySelectFragment(String alias, final boolean[] includeProperty) { return concretePropertySelectFragment( alias, - new InclusionChecker() { - public boolean includeProperty(int propertyNumber) { - return includeProperty[propertyNumber]; - } - } + propertyNumber -> includeProperty[propertyNumber] ); } @@ -2726,7 +2721,7 @@ public String generateUpdateString( 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 // optimistic locking; if we are not updating the version, also don't // check it (unless this is a "generated" version column)! @@ -2738,12 +2733,11 @@ public String generateUpdateString( else if ( isAllOrDirtyOptLocking() && oldFields != null ) { // we are using "all" or "dirty" property-based optimistic locking - boolean[] includeInWhere = entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.ALL - ? - getPropertyUpdateability() + boolean[] includeInWhere = entityMetamodel.getOptimisticLockStyle().isAll() //optimistic-lock="all", include all updatable properties - : - includeProperty; //optimistic-lock="dirty", include all properties we are updating this time + ? getPropertyUpdateability() + //optimistic-lock="dirty", include all properties we are updating this time + : includeProperty; boolean[] versionability = getPropertyVersionability(); Type[] types = getPropertyTypes(); @@ -3470,14 +3464,14 @@ public boolean update( ); // Write any appropriate versioning conditional parameters - if ( useVersion && entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.VERSION ) { + if ( useVersion && entityMetamodel.getOptimisticLockStyle().isVersion()) { if ( checkVersion( includeProperty ) ) { getVersionType().nullSafeSet( update, oldVersion, index, session ); } } else if ( isAllOrDirtyOptLocking() && oldFields != null ) { boolean[] versionability = getPropertyVersionability(); //TODO: is this really necessary???? - boolean[] includeOldField = entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.ALL + boolean[] includeOldField = entityMetamodel.getOptimisticLockStyle().isAll() ? getPropertyUpdateability() : includeProperty; Type[] types = getPropertyTypes(); @@ -3893,8 +3887,7 @@ public void delete(Serializable id, Object version, Object object, SharedSession } protected boolean isAllOrDirtyOptLocking() { - return entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.DIRTY - || entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.ALL; + return entityMetamodel.getOptimisticLockStyle().isAllOrDirty(); } protected String[] generateSQLDeleteStrings(Object[] loadedState) { @@ -5378,12 +5371,11 @@ rs, getPropertyAliases( } - private boolean isValueGenerationRequired(NonIdentifierAttribute attribute, GenerationTiming matchTiming) { - if ( attribute.getType() instanceof ComponentType ) { + public static boolean isValueGenerationRequired(NonIdentifierAttribute attribute, GenerationTiming matchTiming) { + if ( attribute.getType() instanceof ComponentType) { final ComponentType type = (ComponentType) attribute.getType(); - final ValueGeneration[] propertyValueGenerationStrategies = type.getPropertyValueGenerationStrategies(); - for ( ValueGeneration propertyValueGenerationStrategie : propertyValueGenerationStrategies ) { - if ( isReadRequired( propertyValueGenerationStrategie, matchTiming ) ) { + for ( ValueGeneration valueGenerationStrategy : type.getPropertyValueGenerationStrategies() ) { + if ( isReadRequired( valueGenerationStrategy, matchTiming ) ) { return true; } } @@ -5397,16 +5389,10 @@ private boolean isValueGenerationRequired(NonIdentifierAttribute attribute, Gene /** * Whether the given value generation strategy requires to read the value from the database or not. */ - private boolean isReadRequired(ValueGeneration valueGeneration, GenerationTiming matchTiming) { - return valueGeneration != null && - valueGeneration.getValueGenerator() == null && - timingsMatch( valueGeneration.getGenerationTiming(), matchTiming ); - } - - private boolean timingsMatch(GenerationTiming timing, GenerationTiming matchTiming) { - return - ( matchTiming == GenerationTiming.INSERT && timing.includesInsert() ) || - ( matchTiming == GenerationTiming.ALWAYS && timing.includesUpdate() ); + private static boolean isReadRequired(ValueGeneration valueGeneration, GenerationTiming matchTiming) { + return valueGeneration != null + && valueGeneration.getValueGenerator() == null + && valueGeneration.timingMatches( matchTiming ); } public String getIdentifierPropertyName() { @@ -5587,7 +5573,7 @@ public Serializable loadEntityIdByNaturalId( } } - private boolean[] determineValueNullness(Object[] naturalIdValues) { + public static boolean[] determineValueNullness(Object[] naturalIdValues) { boolean[] nullness = new boolean[naturalIdValues.length]; for ( int i = 0; i < naturalIdValues.length; i++ ) { nullness[i] = naturalIdValues[i] == null; diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java index 883dc716b5..8fb6279467 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java @@ -13,7 +13,6 @@ import org.hibernate.boot.model.relational.Database; import org.hibernate.cache.spi.access.EntityDataAccess; import org.hibernate.cache.spi.access.NaturalIdDataAccess; -import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -200,7 +199,7 @@ else if ( persistentClass.isDiscriminatorValueNotNull() ) { 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() + "]" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/ValueGeneration.java b/hibernate-core/src/main/java/org/hibernate/tuple/ValueGeneration.java index 11529d063b..bc02ab284a 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/ValueGeneration.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/ValueGeneration.java @@ -53,4 +53,13 @@ public interface ValueGeneration extends Serializable { * @return The column value to be used in the SQL. */ 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(); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java index 6075fb1ae1..5606e1d47d 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java @@ -395,9 +395,7 @@ else if ( timing == GenerationTiming.ALWAYS ) { hasSubclasses = persistentClass.hasSubclasses(); optimisticLockStyle = persistentClass.getOptimisticLockStyle(); - final boolean isAllOrDirty = - optimisticLockStyle == OptimisticLockStyle.ALL - || optimisticLockStyle == OptimisticLockStyle.DIRTY; + final boolean isAllOrDirty = optimisticLockStyle.isAllOrDirty(); if ( isAllOrDirty && !dynamicUpdate ) { throw new MappingException( "optimistic-lock=all|dirty requires dynamic-update=\"true\": " + name ); }