HHH-6569 : Update persisters and tuplizers to use components

This commit is contained in:
Gail Badner 2012-07-19 13:25:48 -07:00
parent 42a3061f3e
commit ba459aa00c
21 changed files with 543 additions and 134 deletions

View File

@ -50,6 +50,7 @@ import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.factory.IdentifierGeneratorFactory; import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.ValueHolder;
import org.hibernate.metamodel.internal.HibernateTypeHelper.ReflectedCollectionJavaTypes; import org.hibernate.metamodel.internal.HibernateTypeHelper.ReflectedCollectionJavaTypes;
import org.hibernate.metamodel.internal.source.hbm.ListAttributeSource; import org.hibernate.metamodel.internal.source.hbm.ListAttributeSource;
import org.hibernate.metamodel.internal.source.hbm.MapAttributeSource; import org.hibernate.metamodel.internal.source.hbm.MapAttributeSource;
@ -148,6 +149,7 @@ import org.hibernate.metamodel.spi.source.VersionAttributeSource;
import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.config.spi.ConfigurationService; import org.hibernate.service.config.spi.ConfigurationService;
import org.hibernate.tuple.component.ComponentMetamodel;
import org.hibernate.tuple.entity.EntityTuplizer; import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.type.ComponentType; import org.hibernate.type.ComponentType;
import org.hibernate.type.EntityType; import org.hibernate.type.EntityType;
@ -210,6 +212,12 @@ public class Binder {
} }
} }
private SingularAttributeBinding bindIdentifierAttribute(
final AttributeBindingContainer attributeBindingContainer,
final SingularAttributeSource attributeSource) {
return bindSingularAttribute( attributeBindingContainer, attributeSource, true );
}
private AttributeBinding bindAttribute( private AttributeBinding bindAttribute(
final AttributeBindingContainer attributeBindingContainer, final AttributeBindingContainer attributeBindingContainer,
final AttributeSource attributeSource) { final AttributeSource attributeSource) {
@ -220,15 +228,20 @@ public class Binder {
return attributeBinding; return attributeBinding;
} }
return attributeSource.isSingular() ? return attributeSource.isSingular() ?
bindSingularAttribute(attributeBindingContainer,SingularAttributeSource.class.cast( attributeSource )) bindSingularAttribute(
: bindPluralAttribute( attributeBindingContainer,PluralAttributeSource.class.cast( attributeSource ) ); attributeBindingContainer,
SingularAttributeSource.class.cast( attributeSource ),
false
) :
bindPluralAttribute( attributeBindingContainer,PluralAttributeSource.class.cast( attributeSource ) );
} }
// Singular attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Singular attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private SingularAttributeBinding bindSingularAttribute( private SingularAttributeBinding bindSingularAttribute(
final AttributeBindingContainer attributeBindingContainer, final AttributeBindingContainer attributeBindingContainer,
final SingularAttributeSource attributeSource ) { final SingularAttributeSource attributeSource,
boolean isIdentifierAttribute) {
final SingularAttributeNature nature = attributeSource.getNature(); final SingularAttributeNature nature = attributeSource.getNature();
final SingularAttribute attribute = final SingularAttribute attribute =
attributeBindingContainer.getAttributeContainer().locateSingularAttribute( attributeSource.getName() ); attributeBindingContainer.getAttributeContainer().locateSingularAttribute( attributeSource.getName() );
@ -245,7 +258,8 @@ public class Binder {
return bindComponentAttribute( return bindComponentAttribute(
attributeBindingContainer, attributeBindingContainer,
ComponentAttributeSource.class.cast( attributeSource ), ComponentAttributeSource.class.cast( attributeSource ),
attribute attribute,
isIdentifierAttribute
); );
default: default:
throw new NotYetImplementedException( nature.toString() ); throw new NotYetImplementedException( nature.toString() );
@ -290,27 +304,46 @@ public class Binder {
private CompositeAttributeBinding bindComponentAttribute( private CompositeAttributeBinding bindComponentAttribute(
final AttributeBindingContainer attributeBindingContainer, final AttributeBindingContainer attributeBindingContainer,
final ComponentAttributeSource attributeSource, final ComponentAttributeSource attributeSource,
SingularAttribute attribute ) { SingularAttribute attribute,
boolean isAttributeIdentifier) {
final Composite composite; final Composite composite;
ValueHolder<Class<?>> defaultJavaClassReference = null;
if ( attribute == null ) { if ( attribute == null ) {
composite = new Composite( if ( attributeSource.getClassName() != null ) {
attributeSource.getPath(), composite = new Composite(
attributeSource.getClassName(), attributeSource.getPath(),
attributeSource.getClassReference(), attributeSource.getClassName(),
null ); attributeSource.getClassReference() != null ?
attributeSource.getClassReference() :
bindingContext().makeClassReference( attributeSource.getClassName() ),
null
);
// no need for a default because there's an explicit class name provided
}
else {
defaultJavaClassReference = createSingularAttributeJavaType(
attributeBindingContainer.getClassReference(), attributeSource.getName()
);
composite = new Composite(
attributeSource.getPath(),
defaultJavaClassReference.getValue().getName(),
defaultJavaClassReference,
null
);
}
attribute = attributeBindingContainer.getAttributeContainer().createCompositeAttribute( attribute = attributeBindingContainer.getAttributeContainer().createCompositeAttribute(
attributeSource.getName(), attributeSource.getName(),
composite ); composite
} else { );
composite = ( Composite ) attribute.getSingularAttributeType(); }
else {
composite = (Composite) attribute.getSingularAttributeType();
} }
final SingularAttribute referencingAttribute; final SingularAttribute referencingAttribute =
if ( StringHelper.isEmpty( attributeSource.getParentReferenceAttributeName() ) ) { StringHelper.isEmpty( attributeSource.getParentReferenceAttributeName() ) ?
referencingAttribute = null; null :
} else { composite.createSingularAttribute( attributeSource.getParentReferenceAttributeName() );
referencingAttribute = composite.createSingularAttribute( attributeSource.getParentReferenceAttributeName() );
}
final SingularAttributeBinding.NaturalIdMutability naturalIdMutability = attributeSource.getNaturalIdMutability(); final SingularAttributeBinding.NaturalIdMutability naturalIdMutability = attributeSource.getNaturalIdMutability();
final CompositeAttributeBinding attributeBinding = final CompositeAttributeBinding attributeBinding =
attributeBindingContainer.makeComponentAttributeBinding( attributeBindingContainer.makeComponentAttributeBinding(
@ -321,7 +354,28 @@ public class Binder {
attributeSource.isLazy(), attributeSource.isLazy(),
naturalIdMutability, naturalIdMutability,
createMetaAttributeContext( attributeBindingContainer, attributeSource ) ); createMetaAttributeContext( attributeBindingContainer, attributeSource ) );
bindAttributes( attributeBinding, attributeSource ); // TODO: binding the HibernateTypeDescriptor should be simplified since we know the class name already
bindHibernateTypeDescriptor(
attributeBinding.getHibernateTypeDescriptor(),
composite.getClassName(),
null,
defaultJavaClassReference == null ? null : defaultJavaClassReference.getValue().getName()
);
if ( referencingAttribute == null ) {
bindAttributes( attributeBinding, attributeSource );
}
else {
for ( final AttributeSource subAttributeSource : attributeSource.attributeSources() ) {
// TODO: don't create a "parent" attribute binding???
if ( ! subAttributeSource.getName().equals( referencingAttribute.getName() ) ) {
bindAttribute( attributeBinding, subAttributeSource );
}
}
}
Type resolvedType = metadata.getTypeResolver().getTypeFactory().component(
new ComponentMetamodel( attributeBinding, isAttributeIdentifier )
);
bindHibernateResolvedType( attributeBinding.getHibernateTypeDescriptor(), resolvedType );
return attributeBinding; return attributeBinding;
} }
@ -1040,6 +1094,8 @@ public class Binder {
} }
} }
// TODO: simplify how HibernateTypeDescriptor is bound
private void bindHibernateTypeDescriptor( private void bindHibernateTypeDescriptor(
final HibernateTypeDescriptor hibernateTypeDescriptor, final HibernateTypeDescriptor hibernateTypeDescriptor,
final ExplicitHibernateTypeSource explicitTypeSource, final ExplicitHibernateTypeSource explicitTypeSource,
@ -1047,7 +1103,9 @@ public class Binder {
// if there is an explicit type name specified, then there's no reason to // if there is an explicit type name specified, then there's no reason to
// initialize the default Java type name; simply pass a null default instead. // initialize the default Java type name; simply pass a null default instead.
bindHibernateTypeDescriptor( bindHibernateTypeDescriptor(
hibernateTypeDescriptor, explicitTypeSource, explicitTypeSource.getName() == null hibernateTypeDescriptor,
explicitTypeSource,
explicitTypeSource == null || explicitTypeSource.getName() == null
? defaultJavaType.getValue().getName() ? defaultJavaType.getValue().getName()
: null : null
); );
@ -1131,8 +1189,9 @@ public class Binder {
private void bindSimpleIdentifier( final EntityBinding rootEntityBinding, final SimpleIdentifierSource identifierSource ) { private void bindSimpleIdentifier( final EntityBinding rootEntityBinding, final SimpleIdentifierSource identifierSource ) {
// locate the attribute binding // locate the attribute binding
final BasicAttributeBinding idAttributeBinding = final BasicAttributeBinding idAttributeBinding = ( BasicAttributeBinding ) bindIdentifierAttribute(
( BasicAttributeBinding ) bindAttribute( rootEntityBinding, identifierSource.getIdentifierAttributeSource() ); rootEntityBinding, identifierSource.getIdentifierAttributeSource()
);
// Configure ID generator // Configure ID generator
IdGenerator generator = identifierSource.getIdentifierGeneratorDescriptor(); IdGenerator generator = identifierSource.getIdentifierGeneratorDescriptor();
@ -1155,8 +1214,9 @@ public class Binder {
EntityBinding rootEntityBinding, EntityBinding rootEntityBinding,
AggregatedCompositeIdentifierSource identifierSource ) { AggregatedCompositeIdentifierSource identifierSource ) {
// locate the attribute binding // locate the attribute binding
final CompositeAttributeBinding idAttributeBinding = final CompositeAttributeBinding idAttributeBinding = ( CompositeAttributeBinding ) bindIdentifierAttribute(
( CompositeAttributeBinding ) bindAttribute( rootEntityBinding, identifierSource.getIdentifierAttributeSource() ); rootEntityBinding, identifierSource.getIdentifierAttributeSource()
);
// Configure ID generator // Configure ID generator
IdGenerator generator = identifierSource.getIdentifierGeneratorDescriptor(); IdGenerator generator = identifierSource.getIdentifierGeneratorDescriptor();
@ -1181,7 +1241,7 @@ public class Binder {
// locate the attribute bindings for the real attributes // locate the attribute bindings for the real attributes
List< SingularAttributeBinding > idAttributeBindings = new ArrayList< SingularAttributeBinding >(); List< SingularAttributeBinding > idAttributeBindings = new ArrayList< SingularAttributeBinding >();
for ( SingularAttributeSource attributeSource : identifierSource.getAttributeSourcesMakingUpIdentifier() ) { for ( SingularAttributeSource attributeSource : identifierSource.getAttributeSourcesMakingUpIdentifier() ) {
idAttributeBindings.add( ( SingularAttributeBinding ) bindAttribute( rootEntityBinding, attributeSource ) ); idAttributeBindings.add( bindIdentifierAttribute( rootEntityBinding, attributeSource ) );
} }
// Create the synthetic attribute // Create the synthetic attribute
@ -1571,7 +1631,10 @@ public class Binder {
if(isNaturalId){ if(isNaturalId){
addUniqueConstraintForNaturalIdColumn( defaultTable, column ); addUniqueConstraintForNaturalIdColumn( defaultTable, column );
} }
valueBindings.add( new RelationalValueBinding( column, true, !isImmutableNaturalId ) ); valueBindings.add( new RelationalValueBinding(
column,
valueSourceContainer.areValuesIncludedInInsertByDefault(),
valueSourceContainer.areValuesIncludedInUpdateByDefault() && !isImmutableNaturalId ) );
} else { } else {
final String name = attribute.getName(); final String name = attribute.getName();
for ( final RelationalValueSource valueSource : valueSourceContainer.relationalValueSources() ) { for ( final RelationalValueSource valueSource : valueSourceContainer.relationalValueSources() ) {
@ -2074,17 +2137,27 @@ public class Binder {
private static org.hibernate.internal.util.ValueHolder< Class< ? >> createSingularAttributeJavaType( private static org.hibernate.internal.util.ValueHolder< Class< ? >> createSingularAttributeJavaType(
final SingularAttribute attribute ) { final SingularAttribute attribute ) {
return createSingularAttributeJavaType(
attribute.getAttributeContainer().getClassReference(),
attribute.getName()
);
}
private static org.hibernate.internal.util.ValueHolder< Class< ? >> createSingularAttributeJavaType(
final Class< ? > attributeContainerClassReference,
final String attributeName ) {
org.hibernate.internal.util.ValueHolder.DeferredInitializer< Class< ? >> deferredInitializer = org.hibernate.internal.util.ValueHolder.DeferredInitializer< Class< ? >> deferredInitializer =
new org.hibernate.internal.util.ValueHolder.DeferredInitializer< Class< ? >>() { new org.hibernate.internal.util.ValueHolder.DeferredInitializer< Class< ? >>() {
public Class< ? > initialize() { public Class< ? > initialize() {
return ReflectHelper.reflectedPropertyClass( return ReflectHelper.reflectedPropertyClass(
attribute.getAttributeContainer().getClassReference(), attributeContainerClassReference,
attribute.getName() ); attributeName );
} }
}; };
return new org.hibernate.internal.util.ValueHolder< Class< ? >>( deferredInitializer ); return new org.hibernate.internal.util.ValueHolder< Class< ? >>( deferredInitializer );
} }
private static String interpretIdentifierUnsavedValue( IdentifierSource identifierSource, IdGenerator generator ) { private static String interpretIdentifierUnsavedValue( IdentifierSource identifierSource, IdGenerator generator ) {
if ( identifierSource == null ) { if ( identifierSource == null ) {
throw new IllegalArgumentException( "identifierSource must be non-null." ); throw new IllegalArgumentException( "identifierSource must be non-null." );

View File

@ -117,7 +117,8 @@ class ColumnSourceImpl
@Override @Override
public boolean isUnique() { public boolean isUnique() {
return columnElement.isUnique(); // TODO: should TruthValue be returned instead of boolean?
return columnElement.isUnique() != null && columnElement.isUnique().booleanValue();
} }
@Override @Override

View File

@ -26,6 +26,7 @@ package org.hibernate.metamodel.spi.binding;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@ -116,7 +117,7 @@ public class CompositeAttributeBinding
this.path = container.getPathBase() + '.' + attribute.getName(); this.path = container.getPathBase() + '.' + attribute.getName();
if ( subAttributeBindings == null ) { if ( subAttributeBindings == null ) {
attributeBindingMap = new HashMap<String, AttributeBinding>(); attributeBindingMap = new LinkedHashMap<String, AttributeBinding>();
} }
else { else {
HashMap<String, AttributeBinding> map = new HashMap<String, AttributeBinding>(); HashMap<String, AttributeBinding> map = new HashMap<String, AttributeBinding>();
@ -175,8 +176,15 @@ public class CompositeAttributeBinding
@Override @Override
public boolean isNullable() { public boolean isNullable() {
// todo : not sure this is even relevant for components // return false if there are any singular attributes are non-nullable
return false; for ( AttributeBinding attributeBinding : attributeBindings() ) {
// only check singular attributes
if ( attributeBinding.getAttribute().isSingular() &&
! ( (SingularAttributeBinding) attributeBinding ).isNullable() ) {
return false;
}
}
return true;
} }
@Override @Override
@ -205,6 +213,10 @@ public class CompositeAttributeBinding
return null; return null;
} }
public int attributeBindingSpan() {
return attributeBindingMap.size();
}
@Override @Override
public Iterable<AttributeBinding> attributeBindings() { public Iterable<AttributeBinding> attributeBindings() {
return attributeBindingMap.values(); return attributeBindingMap.values();

View File

@ -96,22 +96,30 @@ public final class PropertyAccessorFactory {
* @throws MappingException * @throws MappingException
*/ */
public static PropertyAccessor getPropertyAccessor(AttributeBinding property, EntityMode mode) 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 ) ) {
if ( property.isBackRef() ) { if ( property.isBackRef() ) {
BackRefAttributeBinding backRefAttributeBinding = (BackRefAttributeBinding) property; //TODO: this is temporary in that the end result will probably not take a Property reference per-se.
return new BackrefPropertyAccessor( BackRefAttributeBinding backRefAttributeBinding = (BackRefAttributeBinding) property;
backRefAttributeBinding.getCollectionRole(), backRefAttributeBinding.getEntityName() return new BackrefPropertyAccessor(
); backRefAttributeBinding.getCollectionRole(), backRefAttributeBinding.getEntityName()
);
}
else {
return getPojoPropertyAccessor( property.getPropertyAccessorName() );
}
}
else if (EntityMode.MAP.equals( mode ) ) {
if ( property.isBackRef() ) {
//TODO: this is temporary in that the end result will probably not take a Property reference per-se.
return PropertyAccessorFactory.getPropertyAccessor( null, property.getPropertyAccessorName() );
}
else {
return getDynamicMapPropertyAccessor();
}
}
else {
throw new MappingException( "Unknown entity mode [" + mode + "]" );
} }
else 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 + "]" );
}
} }
/** /**

View File

@ -37,6 +37,7 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
import org.hibernate.metamodel.spi.binding.EntityBinding; import org.hibernate.metamodel.spi.binding.EntityBinding;
/** /**
@ -71,6 +72,23 @@ public class PojoInstantiator implements Instantiator, Serializable {
} }
} }
public PojoInstantiator(CompositeAttributeBinding component, ReflectionOptimizer.InstantiationOptimizer optimizer) {
this.mappedClass = component.getClassReference();
this.isAbstract = ReflectHelper.isAbstractClass( mappedClass );
this.optimizer = optimizer;
this.proxyInterface = null;
this.embeddedIdentifier = false;
try {
constructor = ReflectHelper.getDefaultConstructor(mappedClass);
}
catch ( PropertyNotFoundException pnfe ) {
LOG.noDefaultConstructor(mappedClass.getName());
constructor = null;
}
}
public PojoInstantiator(PersistentClass persistentClass, ReflectionOptimizer.InstantiationOptimizer optimizer) { public PojoInstantiator(PersistentClass persistentClass, ReflectionOptimizer.InstantiationOptimizer optimizer) {
this.mappedClass = persistentClass.getMappedClass(); this.mappedClass = persistentClass.getMappedClass();
this.isAbstract = ReflectHelper.isAbstractClass( mappedClass ); this.isAbstract = ReflectHelper.isAbstractClass( mappedClass );

View File

@ -27,6 +27,7 @@ import java.lang.reflect.Constructor;
import org.hibernate.EntityMode; import org.hibernate.EntityMode;
import org.hibernate.FetchMode; import org.hibernate.FetchMode;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.engine.internal.UnsavedValueFactory; import org.hibernate.engine.internal.UnsavedValueFactory;
import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.IdentifierValue; import org.hibernate.engine.spi.IdentifierValue;
@ -48,6 +49,7 @@ import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
import org.hibernate.property.Getter; import org.hibernate.property.Getter;
import org.hibernate.property.PropertyAccessor; import org.hibernate.property.PropertyAccessor;
import org.hibernate.property.PropertyAccessorFactory; import org.hibernate.property.PropertyAccessorFactory;
import org.hibernate.property.Setter;
import org.hibernate.type.AssociationType; import org.hibernate.type.AssociationType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import org.hibernate.type.VersionType; import org.hibernate.type.VersionType;
@ -122,7 +124,7 @@ public class PropertyFactory {
IdentifierValue unsavedValue = UnsavedValueFactory.getUnsavedIdentifierValue( IdentifierValue unsavedValue = UnsavedValueFactory.getUnsavedIdentifierValue(
mappedUnsavedValue, mappedUnsavedValue,
getGetter( property ), getGetterOrNull( property ),
type, type,
getConstructor( mappedEntity ) getConstructor( mappedEntity )
); );
@ -201,7 +203,7 @@ public class PropertyFactory {
final String mappedUnsavedValue = entityBinding.getHierarchyDetails().getEntityVersion().getUnsavedValue(); final String mappedUnsavedValue = entityBinding.getHierarchyDetails().getEntityVersion().getUnsavedValue();
final VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue( final VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue(
mappedUnsavedValue, mappedUnsavedValue,
getGetter( property ), getGetterOrNull( property ),
(VersionType) property.getHibernateTypeDescriptor().getResolvedTypeMapping(), (VersionType) property.getHibernateTypeDescriptor().getResolvedTypeMapping(),
getConstructor( (EntityBinding) property.getContainer() ) getConstructor( (EntityBinding) property.getContainer() )
); );
@ -307,13 +309,13 @@ public class PropertyFactory {
null, null,
type, type,
lazyAvailable && singularAttributeBinding.isLazy(), lazyAvailable && singularAttributeBinding.isLazy(),
true, // insertable areAnyValuesIncludedInInsert( singularAttributeBinding ), // insertable
true, // updatable areAnyValuesIncludedInUpdate( singularAttributeBinding ), // updatable
propertyGeneration == PropertyGeneration.INSERT propertyGeneration == PropertyGeneration.INSERT
|| propertyGeneration == PropertyGeneration.ALWAYS, || propertyGeneration == PropertyGeneration.ALWAYS,
propertyGeneration == PropertyGeneration.ALWAYS, propertyGeneration == PropertyGeneration.ALWAYS,
singularAttributeBinding.isNullable(), singularAttributeBinding.isNullable(),
alwaysDirtyCheck || areAllValuesIncludedInUpdate( singularAttributeBinding ), alwaysDirtyCheck || areAnyValuesIncludedInUpdate( singularAttributeBinding ),
singularAttributeBinding.isIncludedInOptimisticLocking(), singularAttributeBinding.isIncludedInOptimisticLocking(),
cascadeStyle, cascadeStyle,
fetchMode fetchMode
@ -349,16 +351,22 @@ public class PropertyFactory {
} }
} }
private static boolean areAllValuesIncludedInUpdate(SingularAttributeBinding attributeBinding) { private static boolean areAnyValuesIncludedInInsert(SingularAttributeBinding attributeBinding) {
if ( attributeBinding.hasDerivedValue() ) {
return false;
}
for ( RelationalValueBinding valueBinding : attributeBinding.getRelationalValueBindings() ) { for ( RelationalValueBinding valueBinding : attributeBinding.getRelationalValueBindings() ) {
if ( ! valueBinding.isIncludeInUpdate() ) { if ( valueBinding.isIncludeInInsert() ) {
return false; return true;
} }
} }
return true; return false;
}
private static boolean areAnyValuesIncludedInUpdate(SingularAttributeBinding attributeBinding) {
for ( RelationalValueBinding valueBinding : attributeBinding.getRelationalValueBindings() ) {
if ( valueBinding.isIncludeInUpdate() ) {
return true;
}
}
return false;
} }
private static Constructor getConstructor(PersistentClass persistentClass) { private static Constructor getConstructor(PersistentClass persistentClass) {
@ -396,17 +404,36 @@ public class PropertyFactory {
return pa.getGetter( mappingProperty.getPersistentClass().getMappedClass(), mappingProperty.getName() ); return pa.getGetter( mappingProperty.getPersistentClass().getMappedClass(), mappingProperty.getName() );
} }
private static Getter getGetter(AttributeBinding mappingProperty) { public static Getter getGetter(AttributeBinding mappingProperty) {
if ( mappingProperty == null || mappingProperty.getContainer().getClassReference() == null ) { return getPropertyAccessor( mappingProperty ).getGetter(
return null;
}
PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( mappingProperty, EntityMode.POJO );
return pa.getGetter(
mappingProperty.getContainer().getClassReference(), mappingProperty.getContainer().getClassReference(),
mappingProperty.getAttribute().getName() mappingProperty.getAttribute().getName()
); );
} }
private static Getter getGetterOrNull(AttributeBinding mappingProperty) {
try {
return getGetter( mappingProperty );
}
catch ( PropertyNotFoundException ex ) {
// ignore exception
}
return null;
}
public static Setter getSetter(AttributeBinding mappingProperty) {
return getPropertyAccessor( mappingProperty ).getSetter(
mappingProperty.getContainer().getClassReference(),
mappingProperty.getAttribute().getName()
);
}
private static PropertyAccessor getPropertyAccessor(AttributeBinding mappingProperty) {
// TODO: fix this to work w/ component entity mode also
return PropertyAccessorFactory.getPropertyAccessor(
mappingProperty,
mappingProperty.getContainer().seekEntityBinding().getHierarchyDetails().getEntityMode()
);
}
} }

View File

@ -30,9 +30,12 @@ import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.mapping.Property; import org.hibernate.mapping.Property;
import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
import org.hibernate.property.Getter; import org.hibernate.property.Getter;
import org.hibernate.property.Setter; import org.hibernate.property.Setter;
import org.hibernate.tuple.Instantiator; import org.hibernate.tuple.Instantiator;
import org.hibernate.tuple.PropertyFactory;
/** /**
* Support for tuplizers relating to components. * Support for tuplizers relating to components.
@ -51,6 +54,8 @@ public abstract class AbstractComponentTuplizer implements ComponentTuplizer {
protected abstract Getter buildGetter(Component component, Property prop); protected abstract Getter buildGetter(Component component, Property prop);
protected abstract Setter buildSetter(Component component, Property prop); protected abstract Setter buildSetter(Component component, Property prop);
protected abstract Instantiator buildInstantiator(CompositeAttributeBinding component);
protected AbstractComponentTuplizer(Component component) { protected AbstractComponentTuplizer(Component component) {
propertySpan = component.getPropertySpan(); propertySpan = component.getPropertySpan();
getters = new Getter[propertySpan]; getters = new Getter[propertySpan];
@ -72,6 +77,25 @@ public abstract class AbstractComponentTuplizer implements ComponentTuplizer {
instantiator = buildInstantiator( component ); instantiator = buildInstantiator( component );
} }
protected AbstractComponentTuplizer(CompositeAttributeBinding component) {
propertySpan = component.attributeBindingSpan();
getters = new Getter[propertySpan];
setters = new Setter[propertySpan];
boolean foundCustomAccessor=false;
int i = 0;
for ( AttributeBinding attributeBinding : component.attributeBindings() ) {
getters[i] = PropertyFactory.getGetter( attributeBinding );
setters[i] = PropertyFactory.getSetter( attributeBinding );
if ( !attributeBinding.isBasicPropertyAccessor() ) {
foundCustomAccessor = true;
}
i++;
}
hasCustomAccessors = foundCustomAccessor;
instantiator = buildInstantiator( component );
}
public Object getPropertyValue(Object component, int i) throws HibernateException { public Object getPropertyValue(Object component, int i) throws HibernateException {
return getters[i].get( component ); return getters[i].get( component );
} }

View File

@ -32,6 +32,8 @@ import org.hibernate.EntityMode;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.mapping.Property; import org.hibernate.mapping.Property;
import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
import org.hibernate.tuple.PropertyFactory; import org.hibernate.tuple.PropertyFactory;
import org.hibernate.tuple.StandardProperty; import org.hibernate.tuple.StandardProperty;
@ -45,7 +47,6 @@ public class ComponentMetamodel implements Serializable {
// TODO : will need reference to session factory to fully complete HHH-1907 // TODO : will need reference to session factory to fully complete HHH-1907
// private final SessionFactoryImplementor sessionFactory; // private final SessionFactoryImplementor sessionFactory;
private final String role;
private final boolean isKey; private final boolean isKey;
private final StandardProperty[] properties; private final StandardProperty[] properties;
@ -54,12 +55,11 @@ public class ComponentMetamodel implements Serializable {
// cached for efficiency... // cached for efficiency...
private final int propertySpan; private final int propertySpan;
private final Map propertyIndexes = new HashMap(); private final Map<String,Integer> propertyIndexes = new HashMap<String,Integer>();
// public ComponentMetamodel(Component component, SessionFactoryImplementor sessionFactory) { // public ComponentMetamodel(Component component, SessionFactoryImplementor sessionFactory) {
public ComponentMetamodel(Component component) { public ComponentMetamodel(Component component) {
// this.sessionFactory = sessionFactory; // this.sessionFactory = sessionFactory;
this.role = component.getRoleName();
this.isKey = component.isKey(); this.isKey = component.isKey();
propertySpan = component.getPropertySpan(); propertySpan = component.getPropertySpan();
properties = new StandardProperty[propertySpan]; properties = new StandardProperty[propertySpan];
@ -83,6 +83,31 @@ public class ComponentMetamodel implements Serializable {
) : componentTuplizerFactory.constructTuplizer( tuplizerClassName, component ); ) : componentTuplizerFactory.constructTuplizer( tuplizerClassName, component );
} }
public ComponentMetamodel(CompositeAttributeBinding component, boolean isIdentifierAttributeBinding) {
this.isKey = isIdentifierAttributeBinding;
propertySpan = component.attributeBindingSpan();
properties = new StandardProperty[propertySpan];
int i = 0;
for ( AttributeBinding attributeBinding : component.attributeBindings() ) {
properties[i] = PropertyFactory.buildStandardProperty( attributeBinding, false );
propertyIndexes.put( attributeBinding.getAttribute().getName(), i );
i++;
}
entityMode = component.seekEntityBinding().getHierarchyDetails().getEntityMode();
// todo : move this to SF per HHH-3517; also see HHH-1907 and ComponentMetamodel
final ComponentTuplizerFactory componentTuplizerFactory = new ComponentTuplizerFactory();
// TODO: provide support for custom tuplizer
final String tuplizerClassName = null;
if ( tuplizerClassName == null ) {
componentTuplizer = componentTuplizerFactory.constructDefaultTuplizer( entityMode, component );
}
else {
componentTuplizer = componentTuplizerFactory.constructTuplizer( tuplizerClassName, component );
}
}
public boolean isKey() { public boolean isKey() {
return isKey; return isKey;
} }
@ -103,11 +128,11 @@ public class ComponentMetamodel implements Serializable {
} }
public int getPropertyIndex(String propertyName) { public int getPropertyIndex(String propertyName) {
Integer index = ( Integer ) propertyIndexes.get( propertyName ); Integer index = propertyIndexes.get( propertyName );
if ( index == null ) { if ( index == null ) {
throw new HibernateException( "component does not contain such a property [" + propertyName + "]" ); throw new HibernateException( "component does not contain such a property [" + propertyName + "]" );
} }
return index.intValue(); return index;
} }
public StandardProperty getProperty(String propertyName) { public StandardProperty getProperty(String propertyName) {

View File

@ -32,6 +32,7 @@ import org.hibernate.EntityMode;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
/** /**
* A registry allowing users to define the default {@link ComponentTuplizer} class to use per {@link EntityMode}. * A registry allowing users to define the default {@link ComponentTuplizer} class to use per {@link EntityMode}.
@ -40,6 +41,8 @@ import org.hibernate.mapping.Component;
*/ */
public class ComponentTuplizerFactory implements Serializable { public class ComponentTuplizerFactory implements Serializable {
private static final Class[] COMPONENT_TUP_CTOR_SIG = new Class[] { Component.class }; private static final Class[] COMPONENT_TUP_CTOR_SIG = new Class[] { Component.class };
private static final Class[] COMPONENT_TUP_CTOR_SIG_NEW = new Class[] { CompositeAttributeBinding.class };
private Map<EntityMode,Class<? extends ComponentTuplizer>> defaultImplClassByMode = buildBaseMapping(); private Map<EntityMode,Class<? extends ComponentTuplizer>> defaultImplClassByMode = buildBaseMapping();
@ -53,9 +56,11 @@ public class ComponentTuplizerFactory implements Serializable {
public void registerDefaultTuplizerClass(EntityMode entityMode, Class<? extends ComponentTuplizer> tuplizerClass) { public void registerDefaultTuplizerClass(EntityMode entityMode, Class<? extends ComponentTuplizer> tuplizerClass) {
assert isComponentTuplizerImplementor( tuplizerClass ) assert isComponentTuplizerImplementor( tuplizerClass )
: "Specified tuplizer class [" + tuplizerClass.getName() + "] does not implement " + ComponentTuplizer.class.getName(); : "Specified tuplizer class [" + tuplizerClass.getName() + "] does not implement " + ComponentTuplizer.class.getName();
assert hasProperConstructor( tuplizerClass ) // TODO: for now we need constructors for both PersistentClass and EntityBinding
assert hasProperConstructor( tuplizerClass, COMPONENT_TUP_CTOR_SIG )
: "Specified tuplizer class [" + tuplizerClass.getName() + "] is not properly instantiatable";
assert hasProperConstructor( tuplizerClass, COMPONENT_TUP_CTOR_SIG_NEW )
: "Specified tuplizer class [" + tuplizerClass.getName() + "] is not properly instantiatable"; : "Specified tuplizer class [" + tuplizerClass.getName() + "] is not properly instantiatable";
defaultImplClassByMode.put( entityMode, tuplizerClass ); defaultImplClassByMode.put( entityMode, tuplizerClass );
} }
@ -81,6 +86,28 @@ public class ComponentTuplizerFactory implements Serializable {
} }
} }
/**
* Construct an instance of the given tuplizer class.
*
* @param tuplizerClassName The name of the tuplizer class to instantiate
* @param metadata The metadata for the component.
*
* @return The instantiated tuplizer
*
* @throws HibernateException If class name cannot be resolved to a class reference, or if the
* {@link Constructor#newInstance} call fails.
*/
@SuppressWarnings({ "unchecked" })
public ComponentTuplizer constructTuplizer(String tuplizerClassName, CompositeAttributeBinding metadata) {
try {
Class<? extends ComponentTuplizer> tuplizerClass = ReflectHelper.classForName( tuplizerClassName );
return constructTuplizer( tuplizerClass, metadata );
}
catch ( ClassNotFoundException e ) {
throw new HibernateException( "Could not locate specified tuplizer class [" + tuplizerClassName + "]" );
}
}
/** /**
* Construct an instance of the given tuplizer class. * Construct an instance of the given tuplizer class.
* *
@ -92,7 +119,28 @@ public class ComponentTuplizerFactory implements Serializable {
* @throws HibernateException if the {@link java.lang.reflect.Constructor#newInstance} call fails. * @throws HibernateException if the {@link java.lang.reflect.Constructor#newInstance} call fails.
*/ */
public ComponentTuplizer constructTuplizer(Class<? extends ComponentTuplizer> tuplizerClass, Component metadata) { public ComponentTuplizer constructTuplizer(Class<? extends ComponentTuplizer> tuplizerClass, Component metadata) {
Constructor<? extends ComponentTuplizer> constructor = getProperConstructor( tuplizerClass ); Constructor<? extends ComponentTuplizer> constructor = getProperConstructor( tuplizerClass, COMPONENT_TUP_CTOR_SIG );
assert constructor != null : "Unable to locate proper constructor for tuplizer [" + tuplizerClass.getName() + "]";
try {
return constructor.newInstance( metadata );
}
catch ( Throwable t ) {
throw new HibernateException( "Unable to instantiate default tuplizer [" + tuplizerClass.getName() + "]", t );
}
}
/**
* Construct an instance of the given tuplizer class.
*
* @param tuplizerClass The tuplizer class to instantiate
* @param metadata The metadata for the component.
*
* @return The instantiated tuplizer
*
* @throws HibernateException if the {@link java.lang.reflect.Constructor#newInstance} call fails.
*/
public ComponentTuplizer constructTuplizer(Class<? extends ComponentTuplizer> tuplizerClass, CompositeAttributeBinding metadata) {
Constructor<? extends ComponentTuplizer> constructor = getProperConstructor( tuplizerClass, COMPONENT_TUP_CTOR_SIG_NEW );
assert constructor != null : "Unable to locate proper constructor for tuplizer [" + tuplizerClass.getName() + "]"; assert constructor != null : "Unable to locate proper constructor for tuplizer [" + tuplizerClass.getName() + "]";
try { try {
return constructor.newInstance( metadata ); return constructor.newInstance( metadata );
@ -122,19 +170,41 @@ public class ComponentTuplizerFactory implements Serializable {
return constructTuplizer( tuplizerClass, metadata ); return constructTuplizer( tuplizerClass, metadata );
} }
/**
* Construct am instance of the default tuplizer for the given entity-mode.
*
* @param entityMode The entity mode for which to build a default tuplizer.
* @param metadata The metadata for the component.
*
* @return The instantiated tuplizer
*
* @throws HibernateException If no default tuplizer found for that entity-mode; may be re-thrown from
* {@link #constructTuplizer} too.
*/
public ComponentTuplizer constructDefaultTuplizer(EntityMode entityMode, CompositeAttributeBinding metadata) {
Class<? extends ComponentTuplizer> tuplizerClass = defaultImplClassByMode.get( entityMode );
if ( tuplizerClass == null ) {
throw new HibernateException( "could not determine default tuplizer class to use [" + entityMode + "]" );
}
return constructTuplizer( tuplizerClass, metadata );
}
private boolean isComponentTuplizerImplementor(Class tuplizerClass) { private boolean isComponentTuplizerImplementor(Class tuplizerClass) {
return ReflectHelper.implementsInterface( tuplizerClass, ComponentTuplizer.class ); return ReflectHelper.implementsInterface( tuplizerClass, ComponentTuplizer.class );
} }
@SuppressWarnings({ "unchecked" }) @SuppressWarnings({ "unchecked" })
private boolean hasProperConstructor(Class tuplizerClass) { private boolean hasProperConstructor(Class tuplizerClass, Class[] clazzConstructorSignature) {
return getProperConstructor( tuplizerClass ) != null; return getProperConstructor( tuplizerClass, clazzConstructorSignature ) != null;
} }
private Constructor<? extends ComponentTuplizer> getProperConstructor(Class<? extends ComponentTuplizer> clazz) { private Constructor<? extends ComponentTuplizer> getProperConstructor(
Class<? extends ComponentTuplizer> clazz,
Class[] clazzConstructorSignature) {
Constructor<? extends ComponentTuplizer> constructor = null; Constructor<? extends ComponentTuplizer> constructor = null;
try { try {
constructor = clazz.getDeclaredConstructor( COMPONENT_TUP_CTOR_SIG ); constructor = clazz.getDeclaredConstructor( clazzConstructorSignature );
if ( ! ReflectHelper.isPublic( constructor ) ) { if ( ! ReflectHelper.isPublic( constructor ) ) {
try { try {
// found a constructor, but it was not publicly accessible so try to request accessibility // found a constructor, but it was not publicly accessible so try to request accessibility

View File

@ -27,12 +27,15 @@ import java.util.Map;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.mapping.Property; import org.hibernate.mapping.Property;
import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
import org.hibernate.property.Getter; import org.hibernate.property.Getter;
import org.hibernate.property.PropertyAccessor; import org.hibernate.property.PropertyAccessor;
import org.hibernate.property.PropertyAccessorFactory; import org.hibernate.property.PropertyAccessorFactory;
import org.hibernate.property.Setter; import org.hibernate.property.Setter;
import org.hibernate.tuple.DynamicMapInstantiator; import org.hibernate.tuple.DynamicMapInstantiator;
import org.hibernate.tuple.Instantiator; import org.hibernate.tuple.Instantiator;
import org.hibernate.tuple.PropertyFactory;
/** /**
* A {@link ComponentTuplizer} specific to the dynamic-map entity mode. * A {@link ComponentTuplizer} specific to the dynamic-map entity mode.
@ -66,4 +69,8 @@ public class DynamicMapComponentTuplizer extends AbstractComponentTuplizer {
return buildPropertyAccessor(prop).getSetter( null, prop.getName() ); return buildPropertyAccessor(prop).getSetter( null, prop.getName() );
} }
@Override
protected Instantiator buildInstantiator(CompositeAttributeBinding component) {
return new DynamicMapInstantiator();
}
} }

View File

@ -35,6 +35,8 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.mapping.Property; import org.hibernate.mapping.Property;
import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
import org.hibernate.property.BackrefPropertyAccessor; import org.hibernate.property.BackrefPropertyAccessor;
import org.hibernate.property.Getter; import org.hibernate.property.Getter;
import org.hibernate.property.PropertyAccessor; import org.hibernate.property.PropertyAccessor;
@ -42,6 +44,7 @@ import org.hibernate.property.PropertyAccessorFactory;
import org.hibernate.property.Setter; import org.hibernate.property.Setter;
import org.hibernate.tuple.Instantiator; import org.hibernate.tuple.Instantiator;
import org.hibernate.tuple.PojoInstantiator; import org.hibernate.tuple.PojoInstantiator;
import org.hibernate.tuple.PropertyFactory;
/** /**
* A {@link ComponentTuplizer} specific to the pojo entity mode. * A {@link ComponentTuplizer} specific to the pojo entity mode.
@ -92,6 +95,44 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer {
} }
} }
public PojoComponentTuplizer(CompositeAttributeBinding component) {
super( component );
this.componentClass = component.getClassReference();
String[] getterNames = new String[propertySpan];
String[] setterNames = new String[propertySpan];
Class[] propTypes = new Class[propertySpan];
for ( int i = 0; i < propertySpan; i++ ) {
getterNames[i] = getters[i].getMethodName();
setterNames[i] = setters[i].getMethodName();
propTypes[i] = getters[i].getReturnType();
}
final String parentPropertyName =
component.getParentReference() == null ? null : component.getParentReference().getName();
if ( parentPropertyName == null ) {
parentSetter = null;
parentGetter = null;
}
else {
PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( null );
parentSetter = pa.getSetter( componentClass, parentPropertyName );
parentGetter = pa.getGetter( componentClass, parentPropertyName );
}
if ( hasCustomAccessors || !Environment.useReflectionOptimizer() ) {
optimizer = null;
}
else {
// TODO: here is why we need to make bytecode provider global :(
// TODO : again, fix this after HHH-1907 is complete
optimizer = Environment.getBytecodeProvider().getReflectionOptimizer(
componentClass, getterNames, setterNames, propTypes
);
}
}
public Class getMappedClass() { public Class getMappedClass() {
return componentClass; return componentClass;
} }
@ -159,6 +200,18 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer {
return prop.getSetter( component.getComponentClass() ); return prop.getSetter( component.getComponentClass() );
} }
protected Instantiator buildInstantiator(CompositeAttributeBinding component) {
if ( component.getAttribute().isSynthetic() && ReflectHelper.isAbstractClass( component.getClassReference() ) ) {
return new ProxiedInstantiator( component );
}
if ( optimizer == null ) {
return new PojoInstantiator( component, null );
}
else {
return new PojoInstantiator( component, optimizer.getInstantiationOptimizer() );
}
}
private static class ProxiedInstantiator implements Instantiator { private static class ProxiedInstantiator implements Instantiator {
private final Class proxiedClass; private final Class proxiedClass;
private final BasicProxyFactory factory; private final BasicProxyFactory factory;
@ -177,6 +230,20 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer {
} }
} }
public ProxiedInstantiator(CompositeAttributeBinding component) {
proxiedClass = component.getClassReference();
if ( proxiedClass.isInterface() ) {
factory = Environment.getBytecodeProvider()
.getProxyFactoryFactory()
.buildBasicProxyFactory( null, new Class[] { proxiedClass } );
}
else {
factory = Environment.getBytecodeProvider()
.getProxyFactoryFactory()
.buildBasicProxyFactory( proxiedClass, null );
}
}
public Object instantiate(Serializable id) { public Object instantiate(Serializable id) {
throw new AssertionFailure( "ProxiedInstantiator can only be used to instantiate component" ); throw new AssertionFailure( "ProxiedInstantiator can only be used to instantiate component" );
} }

View File

@ -43,6 +43,7 @@ import org.hibernate.proxy.ProxyFactory;
import org.hibernate.proxy.map.MapProxyFactory; import org.hibernate.proxy.map.MapProxyFactory;
import org.hibernate.tuple.DynamicMapInstantiator; import org.hibernate.tuple.DynamicMapInstantiator;
import org.hibernate.tuple.Instantiator; import org.hibernate.tuple.Instantiator;
import org.hibernate.tuple.PropertyFactory;
/** /**
* An {@link EntityTuplizer} specific to the dynamic-map entity mode. * An {@link EntityTuplizer} specific to the dynamic-map entity mode.
@ -128,21 +129,12 @@ public class DynamicMapEntityTuplizer extends AbstractEntityTuplizer {
return pf; return pf;
} }
private PropertyAccessor buildPropertyAccessor(AttributeBinding mappedProperty) {
if ( mappedProperty.isBackRef() ) {
return PropertyAccessorFactory.getPropertyAccessor( null, mappedProperty.getPropertyAccessorName() );
}
else {
return PropertyAccessorFactory.getDynamicMapPropertyAccessor();
}
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
protected Getter buildPropertyGetter(AttributeBinding mappedProperty) { protected Getter buildPropertyGetter(AttributeBinding mappedProperty) {
return buildPropertyAccessor( mappedProperty ).getGetter( null, mappedProperty.getAttribute().getName() ); return PropertyFactory.getGetter( mappedProperty );
} }
/** /**
@ -150,7 +142,7 @@ public class DynamicMapEntityTuplizer extends AbstractEntityTuplizer {
*/ */
@Override @Override
protected Setter buildPropertySetter(AttributeBinding mappedProperty) { protected Setter buildPropertySetter(AttributeBinding mappedProperty) {
return buildPropertyAccessor( mappedProperty ).getSetter( null, mappedProperty.getAttribute().getName() ); return PropertyFactory.getSetter( mappedProperty );
} }
/** /**

View File

@ -36,7 +36,6 @@ import org.hibernate.EntityMode;
import org.hibernate.EntityNameResolver; import org.hibernate.EntityNameResolver;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.bytecode.instrumentation.internal.FieldInterceptionHelper; import org.hibernate.bytecode.instrumentation.internal.FieldInterceptionHelper;
import org.hibernate.bytecode.instrumentation.spi.FieldInterceptor; import org.hibernate.bytecode.instrumentation.spi.FieldInterceptor;
import org.hibernate.bytecode.spi.ReflectionOptimizer; import org.hibernate.bytecode.spi.ReflectionOptimizer;
@ -52,13 +51,12 @@ import org.hibernate.mapping.Subclass;
import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.EntityBinding; import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.property.Getter; import org.hibernate.property.Getter;
import org.hibernate.property.PropertyAccessor;
import org.hibernate.property.PropertyAccessorFactory;
import org.hibernate.property.Setter; import org.hibernate.property.Setter;
import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.ProxyFactory; import org.hibernate.proxy.ProxyFactory;
import org.hibernate.tuple.Instantiator; import org.hibernate.tuple.Instantiator;
import org.hibernate.tuple.PojoInstantiator; import org.hibernate.tuple.PojoInstantiator;
import org.hibernate.tuple.PropertyFactory;
import org.hibernate.type.CompositeType; import org.hibernate.type.CompositeType;
/** /**
@ -295,11 +293,11 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
} }
for ( AttributeBinding property : entityBinding.attributeBindings() ) { for ( AttributeBinding property : entityBinding.attributeBindings() ) {
Method method = getGetter( property ).getMethod(); Method method = PropertyFactory.getGetter( property ).getMethod();
if ( method != null && Modifier.isFinal( method.getModifiers() ) ) { if ( method != null && Modifier.isFinal( method.getModifiers() ) ) {
LOG.gettersOfLazyClassesCannotBeFinal(entityBinding.getEntity().getName(), property.getAttribute().getName()); LOG.gettersOfLazyClassesCannotBeFinal(entityBinding.getEntity().getName(), property.getAttribute().getName());
} }
method = getSetter( property ).getMethod(); method = PropertyFactory.getSetter( property ).getMethod();
if ( method != null && Modifier.isFinal( method.getModifiers() ) ) { if ( method != null && Modifier.isFinal( method.getModifiers() ) ) {
LOG.settersOfLazyClassesCannotBeFinal(entityBinding.getEntity().getName(), property.getAttribute().getName()); LOG.settersOfLazyClassesCannotBeFinal(entityBinding.getEntity().getName(), property.getAttribute().getName());
} }
@ -448,7 +446,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
*/ */
@Override @Override
protected Getter buildPropertyGetter(AttributeBinding mappedProperty) { protected Getter buildPropertyGetter(AttributeBinding mappedProperty) {
return getGetter( mappedProperty ); return PropertyFactory.getGetter( mappedProperty );
} }
/** /**
@ -456,26 +454,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
*/ */
@Override @Override
protected Setter buildPropertySetter(AttributeBinding mappedProperty) { protected Setter buildPropertySetter(AttributeBinding mappedProperty) {
return getSetter( mappedProperty ); return PropertyFactory.getSetter( mappedProperty );
}
private Getter getGetter(AttributeBinding mappedProperty) throws PropertyNotFoundException, MappingException {
return getPropertyAccessor( mappedProperty ).getGetter(
mappedProperty.getContainer().getClassReference(),
mappedProperty.getAttribute().getName()
);
}
private Setter getSetter(AttributeBinding mappedProperty) throws PropertyNotFoundException, MappingException {
return getPropertyAccessor( mappedProperty ).getSetter(
mappedProperty.getContainer().getClassReference(),
mappedProperty.getAttribute().getName()
);
}
private PropertyAccessor getPropertyAccessor(AttributeBinding mappedProperty) throws MappingException {
// TODO: Fix this then backrefs are working in new metamodel
return PropertyAccessorFactory.getPropertyAccessor( mappedProperty, getEntityMode() );
} }
/** /**

View File

@ -301,6 +301,15 @@ public class EmbeddableBindingTest extends BaseAnnotationBindingTestCase {
private String test; private String test;
@Parent @Parent
private MainEntity parent; private MainEntity parent;
// require getter/setter for parent because of HHH-1614
public MainEntity getParent() {
return parent;
}
public void setParent(MainEntity parent) {
this.parent = parent;
}
} }
@Entity @Entity
@ -331,13 +340,21 @@ public class EmbeddableBindingTest extends BaseAnnotationBindingTestCase {
public interface Car { public interface Car {
int getHorsePower(); int getHorsePower();
void setHorsePower(int horsePower);
} }
@Embeddable @Embeddable
public class CarImpl implements Car { public class CarImpl implements Car {
private int horsePower;
@Override @Override
public int getHorsePower() { public int getHorsePower() {
return 0; return horsePower;
}
@Override
public void setHorsePower(int horsePower) {
this.horsePower = horsePower;
} }
} }

View File

@ -0,0 +1,45 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.test.bidir.onetomany.nonindexed;
import org.junit.Test;
import org.hibernate.cfg.Configuration;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
/**
* @author Gail Badner
*/
public class AbstractBidirectionalOneToManyTest extends BaseCoreFunctionalTestCase {
@Override
public void configure(Configuration cfg) {
super.configure( cfg );
cfg.setProperty( USE_NEW_METADATA_MAPPINGS, "true");
}
@Test
public void testDoNothing() {
}
}

View File

@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.test.bidir.onetomany.nonindexed.inverse; package org.hibernate.test.bidir.onetomany.nonindexed;
import org.junit.Test; import org.junit.Test;
@ -31,20 +31,10 @@ import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
/** /**
* @author Gail Badner * @author Gail Badner
*/ */
public class BidirectionalOneToManyInverseTest extends BaseCoreFunctionalTestCase { public class BidirectionalOneToManyInverseTest extends AbstractBidirectionalOneToManyTest {
@Override @Override
public String[] getMappings() { public String[] getMappings() {
return new String[] { "bidir/onetomany/nonindexed/inverse/ParentChild.hbm.xml" }; return new String[] { "bidir/onetomany/nonindexed/ParentChildInverseOneToMany.hbm.xml" };
}
@Override
public void configure(Configuration cfg) {
super.configure( cfg );
cfg.setProperty( USE_NEW_METADATA_MAPPINGS, "true");
}
@Test
public void testDoNothing() {
} }
} }

View File

@ -0,0 +1,35 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.test.bidir.onetomany.nonindexed;
/**
* @author Gail Badner
*/
public class BidirectionalOneToManyNonInverseTest extends AbstractBidirectionalOneToManyTest {
@Override
public String[] getMappings() {
return new String[] { "bidir/onetomany/nonindexed/ParentChildNonInverseOneToMany.hbm.xml" };
}
}

View File

@ -1,5 +1,5 @@
//$Id: Child.java 5686 2005-02-12 07:27:32Z steveebersole $ //$Id: Child.java 5686 2005-02-12 07:27:32Z steveebersole $
package org.hibernate.test.bidir.onetomany.nonindexed.inverse; package org.hibernate.test.bidir.onetomany.nonindexed;

View File

@ -1,5 +1,5 @@
//$Id: Parent.java 5686 2005-02-12 07:27:32Z steveebersole $ //$Id: Parent.java 5686 2005-02-12 07:27:32Z steveebersole $
package org.hibernate.test.bidir.onetomany.nonindexed.inverse; package org.hibernate.test.bidir.onetomany.nonindexed;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<hibernate-mapping package="org.hibernate.test.bidir.onetomany.nonindexed.inverse" <hibernate-mapping package="org.hibernate.test.bidir.onetomany.nonindexed"
xmlns="http://www.hibernate.org/xsd/hibernate-mapping"> xmlns="http://www.hibernate.org/xsd/hibernate-mapping">
<class name="Child"> <class name="Child">

View File

@ -0,0 +1,19 @@
<?xml version="1.0"?>
<hibernate-mapping package="org.hibernate.test.bidir.onetomany.nonindexed"
xmlns="http://www.hibernate.org/xsd/hibernate-mapping">
<class name="Child">
<id name="name"/>
<property name="age" not-null="true"/>
<many-to-one name="parent" column="parent_id" insert="false" update="false"/>
</class>
<class name="Parent">
<id name="name"/>
<set name="children" cascade="persist,merge" inverse="false">
<key column="parent_id"/>
<one-to-many class="Child"/>
</set>
</class>
</hibernate-mapping>