HHH-11867 - @UpdateTimestamp not working with @Inheritance( strategy = JOINED )
This commit is contained in:
parent
2ad8b3540a
commit
c56b6d7dc7
|
@ -187,7 +187,7 @@ public abstract class AbstractEntityPersister
|
||||||
private final boolean[] propertyUniqueness;
|
private final boolean[] propertyUniqueness;
|
||||||
private final boolean[] propertySelectable;
|
private final boolean[] propertySelectable;
|
||||||
|
|
||||||
private final List<Integer> lobProperties = new ArrayList<Integer>();
|
private final List<Integer> lobProperties = new ArrayList<>();
|
||||||
|
|
||||||
//information about lazy properties of this class
|
//information about lazy properties of this class
|
||||||
private final String[] lazyPropertyNames;
|
private final String[] lazyPropertyNames;
|
||||||
|
@ -224,7 +224,7 @@ public abstract class AbstractEntityPersister
|
||||||
// dynamic filters attached to the class-level
|
// dynamic filters attached to the class-level
|
||||||
private final FilterHelper filterHelper;
|
private final FilterHelper filterHelper;
|
||||||
|
|
||||||
private final Set<String> affectingFetchProfileNames = new HashSet<String>();
|
private final Set<String> affectingFetchProfileNames = new HashSet<>();
|
||||||
|
|
||||||
private final Map uniqueKeyLoaders = new HashMap();
|
private final Map uniqueKeyLoaders = new HashMap();
|
||||||
private final Map lockers = new HashMap();
|
private final Map lockers = new HashMap();
|
||||||
|
@ -1576,8 +1576,8 @@ public abstract class AbstractEntityPersister
|
||||||
.toStatementString();
|
.toStatementString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static interface InclusionChecker {
|
protected interface InclusionChecker {
|
||||||
public boolean includeProperty(int propertyNumber);
|
boolean includeProperty(int propertyNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String concretePropertySelectFragment(String alias, final boolean[] includeProperty) {
|
protected String concretePropertySelectFragment(String alias, final boolean[] includeProperty) {
|
||||||
|
@ -1675,7 +1675,7 @@ public abstract class AbstractEntityPersister
|
||||||
|
|
||||||
// todo : cache this sql...
|
// todo : cache this sql...
|
||||||
String versionIncrementString = generateVersionIncrementUpdateString();
|
String versionIncrementString = generateVersionIncrementUpdateString();
|
||||||
PreparedStatement st = null;
|
PreparedStatement st;
|
||||||
try {
|
try {
|
||||||
st = session
|
st = session
|
||||||
.getJdbcCoordinator()
|
.getJdbcCoordinator()
|
||||||
|
@ -3376,7 +3376,7 @@ public abstract class AbstractEntityPersister
|
||||||
public void update(
|
public void update(
|
||||||
final Serializable id,
|
final Serializable id,
|
||||||
final Object[] fields,
|
final Object[] fields,
|
||||||
final int[] dirtyFields,
|
int[] dirtyFields,
|
||||||
final boolean hasDirtyCollection,
|
final boolean hasDirtyCollection,
|
||||||
final Object[] oldFields,
|
final Object[] oldFields,
|
||||||
final Object oldVersion,
|
final Object oldVersion,
|
||||||
|
@ -3386,12 +3386,32 @@ public abstract class AbstractEntityPersister
|
||||||
|
|
||||||
// apply any pre-update in-memory value generation
|
// apply any pre-update in-memory value generation
|
||||||
if ( getEntityMetamodel().hasPreUpdateGeneratedValues() ) {
|
if ( getEntityMetamodel().hasPreUpdateGeneratedValues() ) {
|
||||||
final InMemoryValueGenerationStrategy[] strategies = getEntityMetamodel().getInMemoryValueGenerationStrategies();
|
final InMemoryValueGenerationStrategy[] valueGenerationStrategies = getEntityMetamodel().getInMemoryValueGenerationStrategies();
|
||||||
for ( int i = 0; i < strategies.length; i++ ) {
|
int valueGenerationStrategiesSize = valueGenerationStrategies.length;
|
||||||
if ( strategies[i] != null && strategies[i].getGenerationTiming().includesUpdate() ) {
|
if ( valueGenerationStrategiesSize != 0 ) {
|
||||||
fields[i] = strategies[i].getValueGenerator().generateValue( (Session) session, object );
|
int[] fieldsPreUpdateNeeded = new int[valueGenerationStrategiesSize];
|
||||||
|
for ( int i = 0; i < valueGenerationStrategiesSize; i++ ) {
|
||||||
|
if ( valueGenerationStrategies[i] != null && valueGenerationStrategies[i].getGenerationTiming()
|
||||||
|
.includesUpdate() ) {
|
||||||
|
fields[i] = valueGenerationStrategies[i].getValueGenerator().generateValue(
|
||||||
|
(Session) session,
|
||||||
|
object
|
||||||
|
);
|
||||||
setPropertyValue( object, i, fields[i] );
|
setPropertyValue( object, i, fields[i] );
|
||||||
// todo : probably best to add to dirtyFields if not-null
|
fieldsPreUpdateNeeded[i] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if ( fieldsPreUpdateNeeded.length != 0 ) {
|
||||||
|
// if ( dirtyFields != null ) {
|
||||||
|
// dirtyFields = ArrayHelper.join( fieldsPreUpdateNeeded, dirtyFields );
|
||||||
|
// }
|
||||||
|
// else if ( hasDirtyCollection ) {
|
||||||
|
// dirtyFields = fieldsPreUpdateNeeded;
|
||||||
|
// }
|
||||||
|
// // no dirty fields and no dirty collections so no update needed ???
|
||||||
|
// }
|
||||||
|
if ( fieldsPreUpdateNeeded.length != 0 && dirtyFields != null ) {
|
||||||
|
dirtyFields = ArrayHelper.join( fieldsPreUpdateNeeded, dirtyFields );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3674,7 +3694,7 @@ public abstract class AbstractEntityPersister
|
||||||
alias,
|
alias,
|
||||||
innerJoin,
|
innerJoin,
|
||||||
includeSubclasses,
|
includeSubclasses,
|
||||||
Collections.<String>emptySet()
|
Collections.emptySet()
|
||||||
).toFromFragmentString();
|
).toFromFragmentString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3699,7 +3719,7 @@ public abstract class AbstractEntityPersister
|
||||||
alias,
|
alias,
|
||||||
innerJoin,
|
innerJoin,
|
||||||
includeSubclasses,
|
includeSubclasses,
|
||||||
Collections.<String>emptySet()
|
Collections.emptySet()
|
||||||
).toWhereFragmentString();
|
).toWhereFragmentString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5380,7 +5400,6 @@ public abstract class AbstractEntityPersister
|
||||||
// EntityDefinition impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// EntityDefinition impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
private EntityIdentifierDefinition entityIdentifierDefinition;
|
private EntityIdentifierDefinition entityIdentifierDefinition;
|
||||||
private Iterable<AttributeDefinition> embeddedCompositeIdentifierAttributes;
|
|
||||||
private Iterable<AttributeDefinition> attributeDefinitions;
|
private Iterable<AttributeDefinition> attributeDefinitions;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -5405,8 +5424,7 @@ public abstract class AbstractEntityPersister
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[][] getPolymorphicJoinColumns(String lhsTableAlias, String propertyPath) {
|
public String[][] getPolymorphicJoinColumns(String lhsTableAlias, String propertyPath) {
|
||||||
Set<String> subclassEntityNames = (Set<String>) getEntityMetamodel()
|
Set<String> subclassEntityNames = getEntityMetamodel().getSubclassEntityNames();
|
||||||
.getSubclassEntityNames();
|
|
||||||
// We will collect all the join columns from the LHS subtypes here
|
// We will collect all the join columns from the LHS subtypes here
|
||||||
List<String[]> polymorphicJoinColumns = new ArrayList<>( subclassEntityNames.size() );
|
List<String[]> polymorphicJoinColumns = new ArrayList<>( subclassEntityNames.size() );
|
||||||
|
|
||||||
|
@ -5522,7 +5540,7 @@ public abstract class AbstractEntityPersister
|
||||||
// to try and drive SQL generation on these (which we do ultimately). A possible solution there
|
// to try and drive SQL generation on these (which we do ultimately). A possible solution there
|
||||||
// would be to delay all SQL generation until postInstantiate
|
// would be to delay all SQL generation until postInstantiate
|
||||||
|
|
||||||
Map<String, AttributeDefinition> attributeDefinitionsByName = new LinkedHashMap<String, AttributeDefinition>();
|
Map<String, AttributeDefinition> attributeDefinitionsByName = new LinkedHashMap<>();
|
||||||
collectAttributeDefinitions( attributeDefinitionsByName, getEntityMetamodel() );
|
collectAttributeDefinitions( attributeDefinitionsByName, getEntityMetamodel() );
|
||||||
|
|
||||||
|
|
||||||
|
@ -5542,7 +5560,7 @@ public abstract class AbstractEntityPersister
|
||||||
// }
|
// }
|
||||||
|
|
||||||
this.attributeDefinitions = Collections.unmodifiableList(
|
this.attributeDefinitions = Collections.unmodifiableList(
|
||||||
new ArrayList<AttributeDefinition>( attributeDefinitionsByName.values() )
|
new ArrayList<>( attributeDefinitionsByName.values() )
|
||||||
);
|
);
|
||||||
// // todo : leverage the attribute definitions housed on EntityMetamodel
|
// // todo : leverage the attribute definitions housed on EntityMetamodel
|
||||||
// // for that to work, we'd have to be able to walk our super entity persister(s)
|
// // for that to work, we'd have to be able to walk our super entity persister(s)
|
||||||
|
|
|
@ -24,7 +24,6 @@ import org.hibernate.engine.OptimisticLockStyle;
|
||||||
import org.hibernate.engine.spi.CascadeStyle;
|
import org.hibernate.engine.spi.CascadeStyle;
|
||||||
import org.hibernate.engine.spi.CascadeStyles;
|
import org.hibernate.engine.spi.CascadeStyles;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.ValueInclusion;
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||||
|
@ -92,7 +91,7 @@ public class EntityMetamodel implements Serializable {
|
||||||
private final InDatabaseValueGenerationStrategy[] inDatabaseValueGenerationStrategies;
|
private final InDatabaseValueGenerationStrategy[] inDatabaseValueGenerationStrategies;
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
private final Map<String, Integer> propertyIndexes = new HashMap<String, Integer>();
|
private final Map<String, Integer> propertyIndexes = new HashMap<>();
|
||||||
private final boolean hasCollections;
|
private final boolean hasCollections;
|
||||||
private final boolean hasMutableProperties;
|
private final boolean hasMutableProperties;
|
||||||
private final boolean hasLazyProperties;
|
private final boolean hasLazyProperties;
|
||||||
|
@ -150,7 +149,7 @@ public class EntityMetamodel implements Serializable {
|
||||||
|
|
||||||
propertySpan = persistentClass.getPropertyClosureSpan();
|
propertySpan = persistentClass.getPropertyClosureSpan();
|
||||||
properties = new NonIdentifierAttribute[propertySpan];
|
properties = new NonIdentifierAttribute[propertySpan];
|
||||||
List<Integer> naturalIdNumbers = new ArrayList<Integer>();
|
List<Integer> naturalIdNumbers = new ArrayList<>();
|
||||||
// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
propertyNames = new String[propertySpan];
|
propertyNames = new String[propertySpan];
|
||||||
propertyTypes = new Type[propertySpan];
|
propertyTypes = new Type[propertySpan];
|
||||||
|
@ -181,8 +180,6 @@ public class EntityMetamodel implements Serializable {
|
||||||
boolean foundCollection = false;
|
boolean foundCollection = false;
|
||||||
boolean foundMutable = false;
|
boolean foundMutable = false;
|
||||||
boolean foundNonIdentifierPropertyNamedId = false;
|
boolean foundNonIdentifierPropertyNamedId = false;
|
||||||
boolean foundInsertGeneratedValue = false;
|
|
||||||
boolean foundUpdateGeneratedValue = false;
|
|
||||||
boolean foundUpdateableNaturalIdProperty = false;
|
boolean foundUpdateableNaturalIdProperty = false;
|
||||||
|
|
||||||
while ( iter.hasNext() ) {
|
while ( iter.hasNext() ) {
|
||||||
|
@ -379,7 +376,7 @@ public class EntityMetamodel implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
entityMode = persistentClass.hasPojoRepresentation() ? EntityMode.POJO : EntityMode.MAP;
|
entityMode = persistentClass.hasPojoRepresentation() ? EntityMode.POJO : EntityMode.MAP;
|
||||||
final EntityTuplizerFactory entityTuplizerFactory = sessionFactory.getSettings().getEntityTuplizerFactory();
|
final EntityTuplizerFactory entityTuplizerFactory = sessionFactory.getSessionFactoryOptions().getEntityTuplizerFactory();
|
||||||
final String tuplizerClassName = persistentClass.getTuplizerImplClassName( entityMode );
|
final String tuplizerClassName = persistentClass.getTuplizerImplClassName( entityMode );
|
||||||
if ( tuplizerClassName == null ) {
|
if ( tuplizerClassName == null ) {
|
||||||
entityTuplizer = entityTuplizerFactory.constructDefaultTuplizer( entityMode, this, persistentClass );
|
entityTuplizer = entityTuplizerFactory.constructDefaultTuplizer( entityMode, this, persistentClass );
|
||||||
|
@ -514,10 +511,6 @@ public class EntityMetamodel implements Serializable {
|
||||||
public ValueGenerationStrategyException(String message) {
|
public ValueGenerationStrategyException(String message) {
|
||||||
super( message );
|
super( message );
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueGenerationStrategyException(String message, Throwable cause) {
|
|
||||||
super( message, cause );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CompositeGenerationStrategyPairBuilder {
|
private static class CompositeGenerationStrategyPairBuilder {
|
||||||
|
@ -540,7 +533,7 @@ public class EntityMetamodel implements Serializable {
|
||||||
|
|
||||||
private void add(InMemoryValueGenerationStrategy inMemoryStrategy) {
|
private void add(InMemoryValueGenerationStrategy inMemoryStrategy) {
|
||||||
if ( inMemoryStrategies == null ) {
|
if ( inMemoryStrategies == null ) {
|
||||||
inMemoryStrategies = new ArrayList<InMemoryValueGenerationStrategy>();
|
inMemoryStrategies = new ArrayList<>();
|
||||||
}
|
}
|
||||||
inMemoryStrategies.add( inMemoryStrategy );
|
inMemoryStrategies.add( inMemoryStrategy );
|
||||||
|
|
||||||
|
@ -551,7 +544,7 @@ public class EntityMetamodel implements Serializable {
|
||||||
|
|
||||||
private void add(InDatabaseValueGenerationStrategy inDatabaseStrategy) {
|
private void add(InDatabaseValueGenerationStrategy inDatabaseStrategy) {
|
||||||
if ( inDatabaseStrategies == null ) {
|
if ( inDatabaseStrategies == null ) {
|
||||||
inDatabaseStrategies = new ArrayList<InDatabaseValueGenerationStrategy>();
|
inDatabaseStrategies = new ArrayList<>();
|
||||||
}
|
}
|
||||||
inDatabaseStrategies.add( inDatabaseStrategy );
|
inDatabaseStrategies.add( inDatabaseStrategy );
|
||||||
|
|
||||||
|
@ -730,81 +723,6 @@ public class EntityMetamodel implements Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ValueInclusion determineInsertValueGenerationType(Property mappingProperty, NonIdentifierAttribute runtimeProperty) {
|
|
||||||
if ( isInsertGenerated( runtimeProperty ) ) {
|
|
||||||
return ValueInclusion.FULL;
|
|
||||||
}
|
|
||||||
else if ( mappingProperty.getValue() instanceof Component ) {
|
|
||||||
if ( hasPartialInsertComponentGeneration( ( Component ) mappingProperty.getValue() ) ) {
|
|
||||||
return ValueInclusion.PARTIAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ValueInclusion.NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isInsertGenerated(NonIdentifierAttribute property) {
|
|
||||||
return property.getValueGenerationStrategy() != null
|
|
||||||
&& property.getValueGenerationStrategy().getGenerationTiming() != GenerationTiming.NEVER;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isInsertGenerated(Property property) {
|
|
||||||
return property.getValueGenerationStrategy() != null
|
|
||||||
&& property.getValueGenerationStrategy().getGenerationTiming() != GenerationTiming.NEVER;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasPartialInsertComponentGeneration(Component component) {
|
|
||||||
Iterator subProperties = component.getPropertyIterator();
|
|
||||||
while ( subProperties.hasNext() ) {
|
|
||||||
final Property prop = ( Property ) subProperties.next();
|
|
||||||
if ( isInsertGenerated( prop ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if ( prop.getValue() instanceof Component ) {
|
|
||||||
if ( hasPartialInsertComponentGeneration( (Component) prop.getValue() ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ValueInclusion determineUpdateValueGenerationType(Property mappingProperty, NonIdentifierAttribute runtimeProperty) {
|
|
||||||
if ( isUpdateGenerated( runtimeProperty ) ) {
|
|
||||||
return ValueInclusion.FULL;
|
|
||||||
}
|
|
||||||
else if ( mappingProperty.getValue() instanceof Component ) {
|
|
||||||
if ( hasPartialUpdateComponentGeneration( ( Component ) mappingProperty.getValue() ) ) {
|
|
||||||
return ValueInclusion.PARTIAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ValueInclusion.NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isUpdateGenerated(Property property) {
|
|
||||||
return property.getValueGenerationStrategy() != null
|
|
||||||
&& property.getValueGenerationStrategy().getGenerationTiming() == GenerationTiming.ALWAYS;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isUpdateGenerated(NonIdentifierAttribute property) {
|
|
||||||
return property.getValueGenerationStrategy() != null
|
|
||||||
&& property.getValueGenerationStrategy().getGenerationTiming() == GenerationTiming.ALWAYS;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasPartialUpdateComponentGeneration(Component component) {
|
|
||||||
Iterator subProperties = component.getPropertyIterator();
|
|
||||||
while ( subProperties.hasNext() ) {
|
|
||||||
Property prop = (Property) subProperties.next();
|
|
||||||
if ( isUpdateGenerated( prop ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if ( prop.getValue() instanceof Component ) {
|
|
||||||
if ( hasPartialUpdateComponentGeneration( ( Component ) prop.getValue() ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void mapPropertyToIndex(Property prop, int i) {
|
private void mapPropertyToIndex(Property prop, int i) {
|
||||||
propertyIndexes.put( prop.getName(), i );
|
propertyIndexes.put( prop.getName(), i );
|
||||||
|
|
Loading…
Reference in New Issue