HHH-6569 : Update persisters and tuplizers to use components
This commit is contained in:
parent
42a3061f3e
commit
ba459aa00c
|
@ -50,6 +50,7 @@ import org.hibernate.id.PersistentIdentifierGenerator;
|
|||
import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.ValueHolder;
|
||||
import org.hibernate.metamodel.internal.HibernateTypeHelper.ReflectedCollectionJavaTypes;
|
||||
import org.hibernate.metamodel.internal.source.hbm.ListAttributeSource;
|
||||
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.entity.EntityPersister;
|
||||
import org.hibernate.service.config.spi.ConfigurationService;
|
||||
import org.hibernate.tuple.component.ComponentMetamodel;
|
||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||
import org.hibernate.type.ComponentType;
|
||||
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(
|
||||
final AttributeBindingContainer attributeBindingContainer,
|
||||
final AttributeSource attributeSource) {
|
||||
|
@ -220,15 +228,20 @@ public class Binder {
|
|||
return attributeBinding;
|
||||
}
|
||||
return attributeSource.isSingular() ?
|
||||
bindSingularAttribute(attributeBindingContainer,SingularAttributeSource.class.cast( attributeSource ))
|
||||
: bindPluralAttribute( attributeBindingContainer,PluralAttributeSource.class.cast( attributeSource ) );
|
||||
bindSingularAttribute(
|
||||
attributeBindingContainer,
|
||||
SingularAttributeSource.class.cast( attributeSource ),
|
||||
false
|
||||
) :
|
||||
bindPluralAttribute( attributeBindingContainer,PluralAttributeSource.class.cast( attributeSource ) );
|
||||
}
|
||||
|
||||
// Singular attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
private SingularAttributeBinding bindSingularAttribute(
|
||||
final AttributeBindingContainer attributeBindingContainer,
|
||||
final SingularAttributeSource attributeSource ) {
|
||||
final SingularAttributeSource attributeSource,
|
||||
boolean isIdentifierAttribute) {
|
||||
final SingularAttributeNature nature = attributeSource.getNature();
|
||||
final SingularAttribute attribute =
|
||||
attributeBindingContainer.getAttributeContainer().locateSingularAttribute( attributeSource.getName() );
|
||||
|
@ -245,7 +258,8 @@ public class Binder {
|
|||
return bindComponentAttribute(
|
||||
attributeBindingContainer,
|
||||
ComponentAttributeSource.class.cast( attributeSource ),
|
||||
attribute
|
||||
attribute,
|
||||
isIdentifierAttribute
|
||||
);
|
||||
default:
|
||||
throw new NotYetImplementedException( nature.toString() );
|
||||
|
@ -290,27 +304,46 @@ public class Binder {
|
|||
private CompositeAttributeBinding bindComponentAttribute(
|
||||
final AttributeBindingContainer attributeBindingContainer,
|
||||
final ComponentAttributeSource attributeSource,
|
||||
SingularAttribute attribute ) {
|
||||
SingularAttribute attribute,
|
||||
boolean isAttributeIdentifier) {
|
||||
final Composite composite;
|
||||
ValueHolder<Class<?>> defaultJavaClassReference = null;
|
||||
if ( attribute == null ) {
|
||||
composite = new Composite(
|
||||
attributeSource.getPath(),
|
||||
attributeSource.getClassName(),
|
||||
attributeSource.getClassReference(),
|
||||
null );
|
||||
if ( attributeSource.getClassName() != null ) {
|
||||
composite = new Composite(
|
||||
attributeSource.getPath(),
|
||||
attributeSource.getClassName(),
|
||||
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(
|
||||
attributeSource.getName(),
|
||||
composite );
|
||||
} else {
|
||||
composite = ( Composite ) attribute.getSingularAttributeType();
|
||||
attributeSource.getName(),
|
||||
composite
|
||||
);
|
||||
}
|
||||
else {
|
||||
composite = (Composite) attribute.getSingularAttributeType();
|
||||
}
|
||||
|
||||
final SingularAttribute referencingAttribute;
|
||||
if ( StringHelper.isEmpty( attributeSource.getParentReferenceAttributeName() ) ) {
|
||||
referencingAttribute = null;
|
||||
} else {
|
||||
referencingAttribute = composite.createSingularAttribute( attributeSource.getParentReferenceAttributeName() );
|
||||
}
|
||||
final SingularAttribute referencingAttribute =
|
||||
StringHelper.isEmpty( attributeSource.getParentReferenceAttributeName() ) ?
|
||||
null :
|
||||
composite.createSingularAttribute( attributeSource.getParentReferenceAttributeName() );
|
||||
final SingularAttributeBinding.NaturalIdMutability naturalIdMutability = attributeSource.getNaturalIdMutability();
|
||||
final CompositeAttributeBinding attributeBinding =
|
||||
attributeBindingContainer.makeComponentAttributeBinding(
|
||||
|
@ -321,7 +354,28 @@ public class Binder {
|
|||
attributeSource.isLazy(),
|
||||
naturalIdMutability,
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1040,6 +1094,8 @@ public class Binder {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: simplify how HibernateTypeDescriptor is bound
|
||||
|
||||
private void bindHibernateTypeDescriptor(
|
||||
final HibernateTypeDescriptor hibernateTypeDescriptor,
|
||||
final ExplicitHibernateTypeSource explicitTypeSource,
|
||||
|
@ -1047,7 +1103,9 @@ public class Binder {
|
|||
// 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.
|
||||
bindHibernateTypeDescriptor(
|
||||
hibernateTypeDescriptor, explicitTypeSource, explicitTypeSource.getName() == null
|
||||
hibernateTypeDescriptor,
|
||||
explicitTypeSource,
|
||||
explicitTypeSource == null || explicitTypeSource.getName() == null
|
||||
? defaultJavaType.getValue().getName()
|
||||
: null
|
||||
);
|
||||
|
@ -1131,8 +1189,9 @@ public class Binder {
|
|||
|
||||
private void bindSimpleIdentifier( final EntityBinding rootEntityBinding, final SimpleIdentifierSource identifierSource ) {
|
||||
// locate the attribute binding
|
||||
final BasicAttributeBinding idAttributeBinding =
|
||||
( BasicAttributeBinding ) bindAttribute( rootEntityBinding, identifierSource.getIdentifierAttributeSource() );
|
||||
final BasicAttributeBinding idAttributeBinding = ( BasicAttributeBinding ) bindIdentifierAttribute(
|
||||
rootEntityBinding, identifierSource.getIdentifierAttributeSource()
|
||||
);
|
||||
|
||||
// Configure ID generator
|
||||
IdGenerator generator = identifierSource.getIdentifierGeneratorDescriptor();
|
||||
|
@ -1155,8 +1214,9 @@ public class Binder {
|
|||
EntityBinding rootEntityBinding,
|
||||
AggregatedCompositeIdentifierSource identifierSource ) {
|
||||
// locate the attribute binding
|
||||
final CompositeAttributeBinding idAttributeBinding =
|
||||
( CompositeAttributeBinding ) bindAttribute( rootEntityBinding, identifierSource.getIdentifierAttributeSource() );
|
||||
final CompositeAttributeBinding idAttributeBinding = ( CompositeAttributeBinding ) bindIdentifierAttribute(
|
||||
rootEntityBinding, identifierSource.getIdentifierAttributeSource()
|
||||
);
|
||||
|
||||
// Configure ID generator
|
||||
IdGenerator generator = identifierSource.getIdentifierGeneratorDescriptor();
|
||||
|
@ -1181,7 +1241,7 @@ public class Binder {
|
|||
// locate the attribute bindings for the real attributes
|
||||
List< SingularAttributeBinding > idAttributeBindings = new ArrayList< SingularAttributeBinding >();
|
||||
for ( SingularAttributeSource attributeSource : identifierSource.getAttributeSourcesMakingUpIdentifier() ) {
|
||||
idAttributeBindings.add( ( SingularAttributeBinding ) bindAttribute( rootEntityBinding, attributeSource ) );
|
||||
idAttributeBindings.add( bindIdentifierAttribute( rootEntityBinding, attributeSource ) );
|
||||
}
|
||||
|
||||
// Create the synthetic attribute
|
||||
|
@ -1571,7 +1631,10 @@ public class Binder {
|
|||
if(isNaturalId){
|
||||
addUniqueConstraintForNaturalIdColumn( defaultTable, column );
|
||||
}
|
||||
valueBindings.add( new RelationalValueBinding( column, true, !isImmutableNaturalId ) );
|
||||
valueBindings.add( new RelationalValueBinding(
|
||||
column,
|
||||
valueSourceContainer.areValuesIncludedInInsertByDefault(),
|
||||
valueSourceContainer.areValuesIncludedInUpdateByDefault() && !isImmutableNaturalId ) );
|
||||
} else {
|
||||
final String name = attribute.getName();
|
||||
for ( final RelationalValueSource valueSource : valueSourceContainer.relationalValueSources() ) {
|
||||
|
@ -2074,17 +2137,27 @@ public class Binder {
|
|||
|
||||
private static org.hibernate.internal.util.ValueHolder< Class< ? >> createSingularAttributeJavaType(
|
||||
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 =
|
||||
new org.hibernate.internal.util.ValueHolder.DeferredInitializer< Class< ? >>() {
|
||||
public Class< ? > initialize() {
|
||||
return ReflectHelper.reflectedPropertyClass(
|
||||
attribute.getAttributeContainer().getClassReference(),
|
||||
attribute.getName() );
|
||||
attributeContainerClassReference,
|
||||
attributeName );
|
||||
}
|
||||
};
|
||||
return new org.hibernate.internal.util.ValueHolder< Class< ? >>( deferredInitializer );
|
||||
}
|
||||
|
||||
|
||||
private static String interpretIdentifierUnsavedValue( IdentifierSource identifierSource, IdGenerator generator ) {
|
||||
if ( identifierSource == null ) {
|
||||
throw new IllegalArgumentException( "identifierSource must be non-null." );
|
||||
|
|
|
@ -117,7 +117,8 @@ class ColumnSourceImpl
|
|||
|
||||
@Override
|
||||
public boolean isUnique() {
|
||||
return columnElement.isUnique();
|
||||
// TODO: should TruthValue be returned instead of boolean?
|
||||
return columnElement.isUnique() != null && columnElement.isUnique().booleanValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,6 +26,7 @@ package org.hibernate.metamodel.spi.binding;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
@ -116,7 +117,7 @@ public class CompositeAttributeBinding
|
|||
this.path = container.getPathBase() + '.' + attribute.getName();
|
||||
|
||||
if ( subAttributeBindings == null ) {
|
||||
attributeBindingMap = new HashMap<String, AttributeBinding>();
|
||||
attributeBindingMap = new LinkedHashMap<String, AttributeBinding>();
|
||||
}
|
||||
else {
|
||||
HashMap<String, AttributeBinding> map = new HashMap<String, AttributeBinding>();
|
||||
|
@ -175,8 +176,15 @@ public class CompositeAttributeBinding
|
|||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
// todo : not sure this is even relevant for components
|
||||
return false;
|
||||
// return false if there are any singular attributes are non-nullable
|
||||
for ( AttributeBinding attributeBinding : attributeBindings() ) {
|
||||
// only check singular attributes
|
||||
if ( attributeBinding.getAttribute().isSingular() &&
|
||||
! ( (SingularAttributeBinding) attributeBinding ).isNullable() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -205,6 +213,10 @@ public class CompositeAttributeBinding
|
|||
return null;
|
||||
}
|
||||
|
||||
public int attributeBindingSpan() {
|
||||
return attributeBindingMap.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AttributeBinding> attributeBindings() {
|
||||
return attributeBindingMap.values();
|
||||
|
|
|
@ -96,22 +96,30 @@ public final class PropertyAccessorFactory {
|
|||
* @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 ( property.isBackRef() ) {
|
||||
BackRefAttributeBinding backRefAttributeBinding = (BackRefAttributeBinding) property;
|
||||
return new BackrefPropertyAccessor(
|
||||
backRefAttributeBinding.getCollectionRole(), backRefAttributeBinding.getEntityName()
|
||||
);
|
||||
if ( null == mode || EntityMode.POJO.equals( mode ) ) {
|
||||
if ( property.isBackRef() ) {
|
||||
//TODO: this is temporary in that the end result will probably not take a Property reference per-se.
|
||||
BackRefAttributeBinding backRefAttributeBinding = (BackRefAttributeBinding) property;
|
||||
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 + "]" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.hibernate.internal.CoreMessageLogger;
|
|||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
|
||||
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) {
|
||||
this.mappedClass = persistentClass.getMappedClass();
|
||||
this.isAbstract = ReflectHelper.isAbstractClass( mappedClass );
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.lang.reflect.Constructor;
|
|||
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.PropertyNotFoundException;
|
||||
import org.hibernate.engine.internal.UnsavedValueFactory;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
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.PropertyAccessor;
|
||||
import org.hibernate.property.PropertyAccessorFactory;
|
||||
import org.hibernate.property.Setter;
|
||||
import org.hibernate.type.AssociationType;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.VersionType;
|
||||
|
@ -122,7 +124,7 @@ public class PropertyFactory {
|
|||
|
||||
IdentifierValue unsavedValue = UnsavedValueFactory.getUnsavedIdentifierValue(
|
||||
mappedUnsavedValue,
|
||||
getGetter( property ),
|
||||
getGetterOrNull( property ),
|
||||
type,
|
||||
getConstructor( mappedEntity )
|
||||
);
|
||||
|
@ -201,7 +203,7 @@ public class PropertyFactory {
|
|||
final String mappedUnsavedValue = entityBinding.getHierarchyDetails().getEntityVersion().getUnsavedValue();
|
||||
final VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue(
|
||||
mappedUnsavedValue,
|
||||
getGetter( property ),
|
||||
getGetterOrNull( property ),
|
||||
(VersionType) property.getHibernateTypeDescriptor().getResolvedTypeMapping(),
|
||||
getConstructor( (EntityBinding) property.getContainer() )
|
||||
);
|
||||
|
@ -307,13 +309,13 @@ public class PropertyFactory {
|
|||
null,
|
||||
type,
|
||||
lazyAvailable && singularAttributeBinding.isLazy(),
|
||||
true, // insertable
|
||||
true, // updatable
|
||||
areAnyValuesIncludedInInsert( singularAttributeBinding ), // insertable
|
||||
areAnyValuesIncludedInUpdate( singularAttributeBinding ), // updatable
|
||||
propertyGeneration == PropertyGeneration.INSERT
|
||||
|| propertyGeneration == PropertyGeneration.ALWAYS,
|
||||
propertyGeneration == PropertyGeneration.ALWAYS,
|
||||
singularAttributeBinding.isNullable(),
|
||||
alwaysDirtyCheck || areAllValuesIncludedInUpdate( singularAttributeBinding ),
|
||||
alwaysDirtyCheck || areAnyValuesIncludedInUpdate( singularAttributeBinding ),
|
||||
singularAttributeBinding.isIncludedInOptimisticLocking(),
|
||||
cascadeStyle,
|
||||
fetchMode
|
||||
|
@ -349,16 +351,22 @@ public class PropertyFactory {
|
|||
}
|
||||
}
|
||||
|
||||
private static boolean areAllValuesIncludedInUpdate(SingularAttributeBinding attributeBinding) {
|
||||
if ( attributeBinding.hasDerivedValue() ) {
|
||||
return false;
|
||||
}
|
||||
private static boolean areAnyValuesIncludedInInsert(SingularAttributeBinding attributeBinding) {
|
||||
for ( RelationalValueBinding valueBinding : attributeBinding.getRelationalValueBindings() ) {
|
||||
if ( ! valueBinding.isIncludeInUpdate() ) {
|
||||
return false;
|
||||
if ( valueBinding.isIncludeInInsert() ) {
|
||||
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) {
|
||||
|
@ -396,17 +404,36 @@ public class PropertyFactory {
|
|||
return pa.getGetter( mappingProperty.getPersistentClass().getMappedClass(), mappingProperty.getName() );
|
||||
}
|
||||
|
||||
private static Getter getGetter(AttributeBinding mappingProperty) {
|
||||
if ( mappingProperty == null || mappingProperty.getContainer().getClassReference() == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( mappingProperty, EntityMode.POJO );
|
||||
return pa.getGetter(
|
||||
public static Getter getGetter(AttributeBinding mappingProperty) {
|
||||
return getPropertyAccessor( mappingProperty ).getGetter(
|
||||
mappingProperty.getContainer().getClassReference(),
|
||||
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()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,9 +30,12 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.mapping.Component;
|
||||
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.Setter;
|
||||
import org.hibernate.tuple.Instantiator;
|
||||
import org.hibernate.tuple.PropertyFactory;
|
||||
|
||||
/**
|
||||
* 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 Setter buildSetter(Component component, Property prop);
|
||||
|
||||
protected abstract Instantiator buildInstantiator(CompositeAttributeBinding component);
|
||||
|
||||
protected AbstractComponentTuplizer(Component component) {
|
||||
propertySpan = component.getPropertySpan();
|
||||
getters = new Getter[propertySpan];
|
||||
|
@ -72,6 +77,25 @@ public abstract class AbstractComponentTuplizer implements ComponentTuplizer {
|
|||
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 {
|
||||
return getters[i].get( component );
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ import org.hibernate.EntityMode;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.mapping.Component;
|
||||
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.StandardProperty;
|
||||
|
||||
|
@ -45,7 +47,6 @@ public class ComponentMetamodel implements Serializable {
|
|||
// TODO : will need reference to session factory to fully complete HHH-1907
|
||||
|
||||
// private final SessionFactoryImplementor sessionFactory;
|
||||
private final String role;
|
||||
private final boolean isKey;
|
||||
private final StandardProperty[] properties;
|
||||
|
||||
|
@ -54,12 +55,11 @@ public class ComponentMetamodel implements Serializable {
|
|||
|
||||
// cached for efficiency...
|
||||
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) {
|
||||
// this.sessionFactory = sessionFactory;
|
||||
this.role = component.getRoleName();
|
||||
this.isKey = component.isKey();
|
||||
propertySpan = component.getPropertySpan();
|
||||
properties = new StandardProperty[propertySpan];
|
||||
|
@ -83,6 +83,31 @@ public class ComponentMetamodel implements Serializable {
|
|||
) : 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() {
|
||||
return isKey;
|
||||
}
|
||||
|
@ -103,11 +128,11 @@ public class ComponentMetamodel implements Serializable {
|
|||
}
|
||||
|
||||
public int getPropertyIndex(String propertyName) {
|
||||
Integer index = ( Integer ) propertyIndexes.get( propertyName );
|
||||
Integer index = propertyIndexes.get( propertyName );
|
||||
if ( index == null ) {
|
||||
throw new HibernateException( "component does not contain such a property [" + propertyName + "]" );
|
||||
}
|
||||
return index.intValue();
|
||||
return index;
|
||||
}
|
||||
|
||||
public StandardProperty getProperty(String propertyName) {
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.hibernate.EntityMode;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
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}.
|
||||
|
@ -40,6 +41,8 @@ import org.hibernate.mapping.Component;
|
|||
*/
|
||||
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 = new Class[] { CompositeAttributeBinding.class };
|
||||
|
||||
|
||||
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) {
|
||||
assert isComponentTuplizerImplementor( tuplizerClass )
|
||||
: "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";
|
||||
|
||||
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.
|
||||
*
|
||||
|
@ -92,7 +119,28 @@ public class ComponentTuplizerFactory implements Serializable {
|
|||
* @throws HibernateException if the {@link java.lang.reflect.Constructor#newInstance} call fails.
|
||||
*/
|
||||
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() + "]";
|
||||
try {
|
||||
return constructor.newInstance( metadata );
|
||||
|
@ -122,19 +170,41 @@ public class ComponentTuplizerFactory implements Serializable {
|
|||
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) {
|
||||
return ReflectHelper.implementsInterface( tuplizerClass, ComponentTuplizer.class );
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
private boolean hasProperConstructor(Class tuplizerClass) {
|
||||
return getProperConstructor( tuplizerClass ) != null;
|
||||
private boolean hasProperConstructor(Class tuplizerClass, Class[] clazzConstructorSignature) {
|
||||
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;
|
||||
try {
|
||||
constructor = clazz.getDeclaredConstructor( COMPONENT_TUP_CTOR_SIG );
|
||||
constructor = clazz.getDeclaredConstructor( clazzConstructorSignature );
|
||||
if ( ! ReflectHelper.isPublic( constructor ) ) {
|
||||
try {
|
||||
// found a constructor, but it was not publicly accessible so try to request accessibility
|
||||
|
|
|
@ -27,12 +27,15 @@ import java.util.Map;
|
|||
|
||||
import org.hibernate.mapping.Component;
|
||||
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.PropertyAccessor;
|
||||
import org.hibernate.property.PropertyAccessorFactory;
|
||||
import org.hibernate.property.Setter;
|
||||
import org.hibernate.tuple.DynamicMapInstantiator;
|
||||
import org.hibernate.tuple.Instantiator;
|
||||
import org.hibernate.tuple.PropertyFactory;
|
||||
|
||||
/**
|
||||
* 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() );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Instantiator buildInstantiator(CompositeAttributeBinding component) {
|
||||
return new DynamicMapInstantiator();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.mapping.Component;
|
||||
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.Getter;
|
||||
import org.hibernate.property.PropertyAccessor;
|
||||
|
@ -42,6 +44,7 @@ import org.hibernate.property.PropertyAccessorFactory;
|
|||
import org.hibernate.property.Setter;
|
||||
import org.hibernate.tuple.Instantiator;
|
||||
import org.hibernate.tuple.PojoInstantiator;
|
||||
import org.hibernate.tuple.PropertyFactory;
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
return componentClass;
|
||||
}
|
||||
|
@ -159,6 +200,18 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer {
|
|||
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 final Class proxiedClass;
|
||||
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) {
|
||||
throw new AssertionFailure( "ProxiedInstantiator can only be used to instantiate component" );
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.hibernate.proxy.ProxyFactory;
|
|||
import org.hibernate.proxy.map.MapProxyFactory;
|
||||
import org.hibernate.tuple.DynamicMapInstantiator;
|
||||
import org.hibernate.tuple.Instantiator;
|
||||
import org.hibernate.tuple.PropertyFactory;
|
||||
|
||||
/**
|
||||
* An {@link EntityTuplizer} specific to the dynamic-map entity mode.
|
||||
|
@ -128,21 +129,12 @@ public class DynamicMapEntityTuplizer extends AbstractEntityTuplizer {
|
|||
return pf;
|
||||
}
|
||||
|
||||
private PropertyAccessor buildPropertyAccessor(AttributeBinding mappedProperty) {
|
||||
if ( mappedProperty.isBackRef() ) {
|
||||
return PropertyAccessorFactory.getPropertyAccessor( null, mappedProperty.getPropertyAccessorName() );
|
||||
}
|
||||
else {
|
||||
return PropertyAccessorFactory.getDynamicMapPropertyAccessor();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
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
|
||||
protected Setter buildPropertySetter(AttributeBinding mappedProperty) {
|
||||
return buildPropertyAccessor( mappedProperty ).getSetter( null, mappedProperty.getAttribute().getName() );
|
||||
return PropertyFactory.getSetter( mappedProperty );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,7 +36,6 @@ import org.hibernate.EntityMode;
|
|||
import org.hibernate.EntityNameResolver;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.PropertyNotFoundException;
|
||||
import org.hibernate.bytecode.instrumentation.internal.FieldInterceptionHelper;
|
||||
import org.hibernate.bytecode.instrumentation.spi.FieldInterceptor;
|
||||
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.EntityBinding;
|
||||
import org.hibernate.property.Getter;
|
||||
import org.hibernate.property.PropertyAccessor;
|
||||
import org.hibernate.property.PropertyAccessorFactory;
|
||||
import org.hibernate.property.Setter;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.ProxyFactory;
|
||||
import org.hibernate.tuple.Instantiator;
|
||||
import org.hibernate.tuple.PojoInstantiator;
|
||||
import org.hibernate.tuple.PropertyFactory;
|
||||
import org.hibernate.type.CompositeType;
|
||||
|
||||
/**
|
||||
|
@ -295,11 +293,11 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
|||
}
|
||||
|
||||
for ( AttributeBinding property : entityBinding.attributeBindings() ) {
|
||||
Method method = getGetter( property ).getMethod();
|
||||
Method method = PropertyFactory.getGetter( property ).getMethod();
|
||||
if ( method != null && Modifier.isFinal( method.getModifiers() ) ) {
|
||||
LOG.gettersOfLazyClassesCannotBeFinal(entityBinding.getEntity().getName(), property.getAttribute().getName());
|
||||
}
|
||||
method = getSetter( property ).getMethod();
|
||||
method = PropertyFactory.getSetter( property ).getMethod();
|
||||
if ( method != null && Modifier.isFinal( method.getModifiers() ) ) {
|
||||
LOG.settersOfLazyClassesCannotBeFinal(entityBinding.getEntity().getName(), property.getAttribute().getName());
|
||||
}
|
||||
|
@ -448,7 +446,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
|||
*/
|
||||
@Override
|
||||
protected Getter buildPropertyGetter(AttributeBinding mappedProperty) {
|
||||
return getGetter( mappedProperty );
|
||||
return PropertyFactory.getGetter( mappedProperty );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -456,26 +454,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
|||
*/
|
||||
@Override
|
||||
protected Setter buildPropertySetter(AttributeBinding mappedProperty) {
|
||||
return 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() );
|
||||
return PropertyFactory.getSetter( mappedProperty );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -301,6 +301,15 @@ public class EmbeddableBindingTest extends BaseAnnotationBindingTestCase {
|
|||
private String test;
|
||||
@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
|
||||
|
@ -331,13 +340,21 @@ public class EmbeddableBindingTest extends BaseAnnotationBindingTestCase {
|
|||
|
||||
public interface Car {
|
||||
int getHorsePower();
|
||||
void setHorsePower(int horsePower);
|
||||
}
|
||||
|
||||
@Embeddable
|
||||
public class CarImpl implements Car {
|
||||
private int horsePower;
|
||||
|
||||
@Override
|
||||
public int getHorsePower() {
|
||||
return 0;
|
||||
return horsePower;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHorsePower(int horsePower) {
|
||||
this.horsePower = horsePower;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
}
|
|
@ -21,7 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.bidir.onetomany.nonindexed.inverse;
|
||||
package org.hibernate.test.bidir.onetomany.nonindexed;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -31,20 +31,10 @@ import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
|||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class BidirectionalOneToManyInverseTest extends BaseCoreFunctionalTestCase {
|
||||
public class BidirectionalOneToManyInverseTest extends AbstractBidirectionalOneToManyTest {
|
||||
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
return new String[] { "bidir/onetomany/nonindexed/inverse/ParentChild.hbm.xml" };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(Configuration cfg) {
|
||||
super.configure( cfg );
|
||||
cfg.setProperty( USE_NEW_METADATA_MAPPINGS, "true");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoNothing() {
|
||||
return new String[] { "bidir/onetomany/nonindexed/ParentChildInverseOneToMany.hbm.xml" };
|
||||
}
|
||||
}
|
|
@ -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" };
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
//$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;
|
||||
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
//$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.Set;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<?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">
|
||||
|
||||
<class name="Child">
|
|
@ -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>
|
Loading…
Reference in New Issue