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.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." );
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 + "]" );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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" );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
* 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() {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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 $
|
//$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 $
|
//$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;
|
||||||
|
|
|
@ -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">
|
|
@ -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