HHH-6360 : Build basic properties from an AttributeBinding
This commit is contained in:
parent
0f88ec8b71
commit
1d26ac1e12
|
@ -30,6 +30,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.metamodel.binding.AttributeBinding;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
|
@ -79,7 +80,31 @@ public final class PropertyAccessorFactory {
|
|||
else {
|
||||
throw new MappingException( "Unknown entity mode [" + mode + "]" );
|
||||
}
|
||||
} /**
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a PropertyAccessor instance based on the given property definition and
|
||||
* entity mode.
|
||||
*
|
||||
* @param property The property for which to retrieve an accessor.
|
||||
* @param mode The mode for the resulting entity.
|
||||
* @return An appropriate accessor.
|
||||
* @throws MappingException
|
||||
*/
|
||||
public static PropertyAccessor getPropertyAccessor(AttributeBinding property, EntityMode mode) throws MappingException {
|
||||
//TODO: this is temporary in that the end result will probably not take a Property reference per-se.
|
||||
if ( null == mode || EntityMode.POJO.equals( mode ) ) {
|
||||
return getPojoPropertyAccessor( property.getPropertyAccessorName() );
|
||||
}
|
||||
else if ( EntityMode.MAP.equals( mode ) ) {
|
||||
return getDynamicMapPropertyAccessor();
|
||||
}
|
||||
else {
|
||||
throw new MappingException( "Unknown entity mode [" + mode + "]" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreives a PropertyAccessor specific for a PojoRepresentation with the given access strategy.
|
||||
*
|
||||
* @param pojoAccessorStrategy The access strategy.
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
package org.hibernate.tuple;
|
||||
import java.lang.reflect.Constructor;
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.engine.spi.IdentifierValue;
|
||||
import org.hibernate.engine.internal.UnsavedValueFactory;
|
||||
import org.hibernate.engine.spi.VersionValue;
|
||||
|
@ -33,6 +35,11 @@ import org.hibernate.mapping.KeyValue;
|
|||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.mapping.PropertyGeneration;
|
||||
import org.hibernate.metamodel.binding.AttributeBinding;
|
||||
import org.hibernate.metamodel.binding.EntityBinding;
|
||||
import org.hibernate.metamodel.binding.EntityIdentifier;
|
||||
import org.hibernate.metamodel.binding.PluralAttributeBinding;
|
||||
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
|
||||
import org.hibernate.property.Getter;
|
||||
import org.hibernate.property.PropertyAccessor;
|
||||
import org.hibernate.property.PropertyAccessorFactory;
|
||||
|
@ -91,6 +98,50 @@ public class PropertyFactory {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an IdentifierProperty representation of the for a given entity mapping.
|
||||
*
|
||||
* @param mappedEntity The mapping definition of the entity.
|
||||
* @param generator The identifier value generator to use for this identifier.
|
||||
* @return The appropriate IdentifierProperty definition.
|
||||
*/
|
||||
public static IdentifierProperty buildIdentifierProperty(EntityBinding mappedEntity, IdentifierGenerator generator) {
|
||||
|
||||
final SimpleAttributeBinding property = mappedEntity.getEntityIdentifier().getValueBinding();
|
||||
|
||||
// TODO: the following will cause an NPE with "virtual" IDs; how should they be set?
|
||||
final String mappedUnsavedValue = property.getUnsavedValue();
|
||||
final Type type = property.getHibernateTypeDescriptor().getExplicitType();
|
||||
|
||||
IdentifierValue unsavedValue = UnsavedValueFactory.getUnsavedIdentifierValue(
|
||||
mappedUnsavedValue,
|
||||
getGetter( property ),
|
||||
type,
|
||||
getConstructor( mappedEntity )
|
||||
);
|
||||
|
||||
if ( property == null ) {
|
||||
// this is a virtual id property...
|
||||
return new IdentifierProperty(
|
||||
type,
|
||||
mappedEntity.getEntityIdentifier().isEmbedded(),
|
||||
mappedEntity.getEntityIdentifier().isIdentifierMapper(),
|
||||
unsavedValue,
|
||||
generator
|
||||
);
|
||||
}
|
||||
else {
|
||||
return new IdentifierProperty(
|
||||
property.getAttribute().getName(),
|
||||
property.getNodeName(),
|
||||
type,
|
||||
mappedEntity.getEntityIdentifier().isEmbedded(),
|
||||
unsavedValue,
|
||||
generator
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a VersionProperty representation for an entity mapping given its
|
||||
* version mapping Property.
|
||||
|
@ -128,6 +179,45 @@ public class PropertyFactory {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a VersionProperty representation for an entity mapping given its
|
||||
* version mapping Property.
|
||||
*
|
||||
* @param property The version mapping Property.
|
||||
* @param lazyAvailable Is property lazy loading currently available.
|
||||
* @return The appropriate VersionProperty definition.
|
||||
*/
|
||||
public static VersionProperty buildVersionProperty(SimpleAttributeBinding property, boolean lazyAvailable) {
|
||||
String mappedUnsavedValue = ( (KeyValue) property.getValue() ).getNullValue();
|
||||
|
||||
VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue(
|
||||
mappedUnsavedValue,
|
||||
getGetter( property ),
|
||||
( VersionType ) property.getHibernateTypeDescriptor().getExplicitType(),
|
||||
getConstructor( property.getEntityBinding() )
|
||||
);
|
||||
|
||||
boolean lazy = lazyAvailable && property.isLazy();
|
||||
|
||||
return new VersionProperty(
|
||||
property.getAttribute().getName(),
|
||||
property.getNodeName(),
|
||||
property.getHibernateTypeDescriptor().getExplicitType(),
|
||||
lazy,
|
||||
property.isInsertable(),
|
||||
property.isUpdatable(),
|
||||
property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS,
|
||||
property.getGeneration() == PropertyGeneration.ALWAYS,
|
||||
property.isNullable(),
|
||||
property.isUpdatable() && !lazy,
|
||||
property.isOptimisticLockable(),
|
||||
// TODO: get cascadeStyle from property when HHH-6355 is fixed; for now, assume NONE
|
||||
//property.getCascadeStyle(),
|
||||
CascadeStyle.NONE,
|
||||
unsavedValue
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a "standard" (i.e., non-identifier and non-version) based on the given
|
||||
* mapped property.
|
||||
|
@ -167,6 +257,80 @@ public class PropertyFactory {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a "standard" (i.e., non-identifier and non-version) based on the given
|
||||
* mapped property.
|
||||
*
|
||||
* @param property The mapped property.
|
||||
* @param lazyAvailable Is property lazy loading currently available.
|
||||
* @return The appropriate StandardProperty definition.
|
||||
*/
|
||||
public static StandardProperty buildStandardProperty(AttributeBinding property, boolean lazyAvailable) {
|
||||
|
||||
final Type type = property.getHibernateTypeDescriptor().getExplicitType();
|
||||
|
||||
// we need to dirty check collections, since they can cause an owner
|
||||
// version number increment
|
||||
|
||||
// we need to dirty check many-to-ones with not-found="ignore" in order
|
||||
// to update the cache (not the database), since in this case a null
|
||||
// entity reference can lose information
|
||||
|
||||
boolean alwaysDirtyCheck = type.isAssociationType() &&
|
||||
( (AssociationType) type ).isAlwaysDirtyChecked();
|
||||
|
||||
if ( property.isSimpleValue() ) {
|
||||
SimpleAttributeBinding simpleProperty = ( SimpleAttributeBinding ) property;
|
||||
return new StandardProperty(
|
||||
simpleProperty.getAttribute().getName(),
|
||||
simpleProperty.getNodeName(),
|
||||
type,
|
||||
lazyAvailable && simpleProperty.isLazy(),
|
||||
simpleProperty.isInsertable(),
|
||||
simpleProperty.isUpdatable(),
|
||||
simpleProperty.getGeneration() == PropertyGeneration.INSERT || simpleProperty.getGeneration() == PropertyGeneration.ALWAYS,
|
||||
simpleProperty.getGeneration() == PropertyGeneration.ALWAYS,
|
||||
simpleProperty.isNullable(),
|
||||
alwaysDirtyCheck || simpleProperty.isUpdatable(),
|
||||
simpleProperty.isOptimisticLockable(),
|
||||
// TODO: get cascadeStyle from simpleProperty when HHH-6355 is fixed; for now, assume NONE
|
||||
//simpleProperty.getCascadeStyle(),
|
||||
CascadeStyle.NONE,
|
||||
// TODO: get fetchMode() from simpleProperty when HHH-6357 is fixed; for now, assume FetchMode.DEFAULT
|
||||
//simpleProperty.getFetchMode()
|
||||
FetchMode.DEFAULT
|
||||
);
|
||||
}
|
||||
else {
|
||||
PluralAttributeBinding pluralProperty = ( PluralAttributeBinding ) property;
|
||||
|
||||
return new StandardProperty(
|
||||
pluralProperty.getAttribute().getName(),
|
||||
pluralProperty.getNodeName(),
|
||||
type,
|
||||
lazyAvailable && pluralProperty.isLazy(),
|
||||
// TODO: fix this when HHH-6356 is fixed; for now assume PluralAttributeBinding is updatable and insertable
|
||||
// pluralProperty.isInsertable(),
|
||||
//pluralProperty.isUpdatable(),
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
pluralProperty.isNullable(),
|
||||
// TODO: fix this when HHH-6356 is fixed; for now assume PluralAttributeBinding is updatable and insertable
|
||||
//alwaysDirtyCheck || pluralProperty.isUpdatable(),
|
||||
true,
|
||||
pluralProperty.isOptimisticLocked(),
|
||||
// TODO: get cascadeStyle from property when HHH-6355 is fixed; for now, assume NONE
|
||||
//pluralProperty.getCascadeStyle(),
|
||||
CascadeStyle.NONE,
|
||||
// TODO: get fetchMode() from simpleProperty when HHH-6357 is fixed; for now, assume FetchMode.DEFAULT
|
||||
//pluralProperty.getFetchMode()
|
||||
FetchMode.DEFAULT
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static Constructor getConstructor(PersistentClass persistentClass) {
|
||||
if ( persistentClass == null || !persistentClass.hasPojoRepresentation() ) {
|
||||
return null;
|
||||
|
@ -180,6 +344,19 @@ public class PropertyFactory {
|
|||
}
|
||||
}
|
||||
|
||||
private static Constructor getConstructor(EntityBinding entityBinding) {
|
||||
if ( entityBinding == null || entityBinding.getEntity().getJavaType() == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return ReflectHelper.getDefaultConstructor( entityBinding.getEntity().getJavaType().getClassReference() );
|
||||
}
|
||||
catch( Throwable t ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Getter getGetter(Property mappingProperty) {
|
||||
if ( mappingProperty == null || !mappingProperty.getPersistentClass().hasPojoRepresentation() ) {
|
||||
return null;
|
||||
|
@ -189,4 +366,17 @@ public class PropertyFactory {
|
|||
return pa.getGetter( mappingProperty.getPersistentClass().getMappedClass(), mappingProperty.getName() );
|
||||
}
|
||||
|
||||
private static Getter getGetter(AttributeBinding mappingProperty) {
|
||||
if ( mappingProperty == null || mappingProperty.getEntityBinding().getEntity().getJavaType() == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( mappingProperty, EntityMode.POJO );
|
||||
return pa.getGetter(
|
||||
mappingProperty.getEntityBinding().getEntity().getJavaType().getClassReference(),
|
||||
mappingProperty.getAttribute().getName()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -345,12 +345,10 @@ public class EntityMetamodel implements Serializable {
|
|||
rootName = name;
|
||||
entityType = sessionFactory.getTypeResolver().getTypeFactory().manyToOne( name );
|
||||
|
||||
// TODO: fix this when Type is available (HHH-6360)
|
||||
//identifierProperty = PropertyFactory.buildIdentifierProperty(
|
||||
// entityBinding,
|
||||
// sessionFactory.getIdentifierGenerator( rootName )
|
||||
//);
|
||||
identifierProperty = null;
|
||||
identifierProperty = PropertyFactory.buildIdentifierProperty(
|
||||
entityBinding,
|
||||
sessionFactory.getIdentifierGenerator( rootName )
|
||||
);
|
||||
|
||||
versioned = entityBinding.isVersioned();
|
||||
|
||||
|
@ -410,14 +408,13 @@ public class EntityMetamodel implements Serializable {
|
|||
continue;
|
||||
}
|
||||
|
||||
// TODO: fix this when Type is available (HHH-6360)
|
||||
//if ( attributeBinding == entityBinding.getVersioningValueBinding() ) {
|
||||
// tempVersionProperty = i;
|
||||
// properties[i] = PropertyFactory.buildVersionProperty( entityBinding.getVersioningValueBinding(), lazyAvailable );
|
||||
//}
|
||||
//else {
|
||||
// properties[i] = PropertyFactory.buildStandardProperty( attributeBinding, lazyAvailable );
|
||||
//}
|
||||
if ( attributeBinding == entityBinding.getVersioningValueBinding() ) {
|
||||
tempVersionProperty = i;
|
||||
properties[i] = PropertyFactory.buildVersionProperty( entityBinding.getVersioningValueBinding(), lazyAvailable );
|
||||
}
|
||||
else {
|
||||
properties[i] = PropertyFactory.buildStandardProperty( attributeBinding, lazyAvailable );
|
||||
}
|
||||
|
||||
// TODO: fix when natural IDs are added (HHH-6354)
|
||||
//if ( attributeBinding.isNaturalIdentifier() ) {
|
||||
|
|
Loading…
Reference in New Issue