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 b05d73ae4d..5b5a4166d3 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 @@ -121,6 +121,7 @@ import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.type.AssociationType; import org.hibernate.type.CollectionType; +import org.hibernate.type.ComponentType; import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; @@ -4731,8 +4732,7 @@ public abstract class AbstractEntityPersister int propertyIndex = -1; for ( NonIdentifierAttribute attribute : entityMetamodel.getProperties() ) { propertyIndex++; - final ValueGeneration valueGeneration = attribute.getValueGenerationStrategy(); - if ( isReadRequired( valueGeneration, matchTiming ) ) { + if ( isValueGenerationRequired( attribute, matchTiming ) ) { final Object hydratedState = attribute.getType().hydrate( rs, getPropertyAliases( "", @@ -4743,6 +4743,7 @@ public abstract class AbstractEntityPersister setPropertyValue( entity, propertyIndex, state[propertyIndex] ); } } + // for ( int i = 0; i < getPropertySpan(); i++ ) { // if ( includeds[i] != ValueInclusion.NONE ) { // Object hydratedState = getPropertyTypes()[i].hydrate( rs, getPropertyAliases( "", i ), session, entity ); @@ -4772,6 +4773,22 @@ public abstract class AbstractEntityPersister } + private boolean isValueGenerationRequired(NonIdentifierAttribute attribute, GenerationTiming matchTiming) { + if ( attribute.getType() instanceof ComponentType ) { + final ComponentType type = (ComponentType) attribute.getType(); + final ValueGeneration[] propertyValueGenerationStrategies = type.getPropertyValueGenerationStrategies(); + for ( int i = 0; i < propertyValueGenerationStrategies.length; i++ ) { + if ( isReadRequired( propertyValueGenerationStrategies[i], matchTiming ) ) { + return true; + } + } + return false; + } + else { + return isReadRequired( attribute.getValueGenerationStrategy(), matchTiming ); + } + } + /** * Whether the given value generation strategy requires to read the value from the database or not. */ 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 eae6835d32..11529d063b 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/ValueGeneration.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/ValueGeneration.java @@ -6,12 +6,14 @@ */ package org.hibernate.tuple; +import java.io.Serializable; + /** * Describes the generation of property values. * * @author Steve Ebersole */ -public interface ValueGeneration { +public interface ValueGeneration extends Serializable { /** * When is this value generated : NEVER, INSERT, ALWAYS (INSERT+UPDATE) * diff --git a/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java b/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java index 714abb0cee..b73c20933f 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java @@ -28,6 +28,7 @@ import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.tuple.StandardProperty; +import org.hibernate.tuple.ValueGeneration; import org.hibernate.tuple.component.ComponentMetamodel; import org.hibernate.tuple.component.ComponentTuplizer; @@ -41,6 +42,7 @@ public class ComponentType extends AbstractType implements CompositeType, Proced private final TypeFactory.TypeScope typeScope; private final String[] propertyNames; private final Type[] propertyTypes; + private final ValueGeneration[] propertyValueGenerationStrategies; private final boolean[] propertyNullability; protected final int propertySpan; private final CascadeStyle[] cascade; @@ -58,6 +60,7 @@ public class ComponentType extends AbstractType implements CompositeType, Proced this.propertySpan = metamodel.getPropertySpan(); this.propertyNames = new String[propertySpan]; this.propertyTypes = new Type[propertySpan]; + this.propertyValueGenerationStrategies = new ValueGeneration[propertySpan]; this.propertyNullability = new boolean[propertySpan]; this.cascade = new CascadeStyle[propertySpan]; this.joinedFetch = new FetchMode[propertySpan]; @@ -72,6 +75,7 @@ public class ComponentType extends AbstractType implements CompositeType, Proced if ( !prop.isNullable() ) { hasNotNullProperty = true; } + this.propertyValueGenerationStrategies[i] = prop.getValueGenerationStrategy(); } this.entityMode = metamodel.getEntityMode(); @@ -448,6 +452,10 @@ public class ComponentType extends AbstractType implements CompositeType, Proced return propertyTypes; } + public ValueGeneration[] getPropertyValueGenerationStrategies() { + return propertyValueGenerationStrategies; + } + @Override public String getName() { return "component" + ArrayHelper.toString( propertyNames );