split UserComponentType out from ComponentType
and add CompositeType.replacePropertyValues() this refactoring results in significant simplifications/cleanliness
This commit is contained in:
parent
47024e7bd5
commit
2c5ee8f088
|
@ -26,6 +26,7 @@ import org.hibernate.boot.model.relational.SqlStringGenerationContext;
|
|||
import org.hibernate.boot.model.source.internal.hbm.MappingDocument;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||
import org.hibernate.boot.spi.BootstrapContext;
|
||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.spi.Mapping;
|
||||
|
@ -42,9 +43,13 @@ import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
|||
import org.hibernate.property.access.spi.Setter;
|
||||
import org.hibernate.generator.Generator;
|
||||
import org.hibernate.generator.BeforeExecutionGenerator;
|
||||
import org.hibernate.resource.beans.internal.FallbackBeanInstanceProducer;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||
import org.hibernate.type.ComponentType;
|
||||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.EmbeddedComponentType;
|
||||
import org.hibernate.type.UserComponentType;
|
||||
import org.hibernate.usertype.CompositeUserType;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.hibernate.generator.EventType.INSERT;
|
||||
|
@ -327,6 +332,10 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
|||
}
|
||||
|
||||
public Class<?> getComponentClass() throws MappingException {
|
||||
if ( componentClassName == null ) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
final ClassLoaderService classLoaderService = getMetadata()
|
||||
.getMetadataBuildingOptions()
|
||||
.getServiceRegistry()
|
||||
|
@ -338,6 +347,7 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
|||
throw new MappingException("component class not found: " + componentClassName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PersistentClass getOwner() {
|
||||
return owner;
|
||||
|
@ -371,12 +381,22 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
|||
this.dynamic = dynamic;
|
||||
}
|
||||
|
||||
private CompositeUserType<?> createCompositeUserType(Component component) {
|
||||
final BootstrapContext bootstrapContext = getBuildingContext().getBootstrapContext();
|
||||
final Class<CompositeUserType<?>> customTypeClass =
|
||||
bootstrapContext.getClassLoaderAccess().classForName( component.getTypeName() );
|
||||
return getBuildingContext().getBuildingOptions().disallowExtensionsInCdi()
|
||||
? FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( customTypeClass )
|
||||
: bootstrapContext.getServiceRegistry().requireService( ManagedBeanRegistry.class )
|
||||
.getBean( customTypeClass ).getBeanInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompositeType getType() throws MappingException {
|
||||
// Resolve the type of the value once and for all as this operation generates a proxy class
|
||||
// for each invocation.
|
||||
// Unfortunately, there's no better way of doing that as none of the classes are immutable and
|
||||
// we can't know for sure the current state of the property or the value.
|
||||
// Unfortunately, there's no better way of doing that as none of the classes are immutable,
|
||||
// and we can't know for sure the current state of the property or the value.
|
||||
CompositeType localType = type;
|
||||
|
||||
if ( localType == null ) {
|
||||
|
@ -387,11 +407,18 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
|
|||
// Other components should be sorted already
|
||||
sortProperties( true );
|
||||
|
||||
final String typeName = getTypeName();
|
||||
if ( typeName == null ) {
|
||||
localType = isEmbedded()
|
||||
? new EmbeddedComponentType( this, originalPropertyOrder, getBuildingContext() )
|
||||
: new ComponentType( this, originalPropertyOrder, getBuildingContext() );
|
||||
? new EmbeddedComponentType( this, originalPropertyOrder )
|
||||
: new ComponentType( this, originalPropertyOrder );
|
||||
}
|
||||
else {
|
||||
final CompositeUserType<?> compositeUserType = createCompositeUserType( this );
|
||||
localType = new UserComponentType<>( this, originalPropertyOrder, compositeUserType );
|
||||
}
|
||||
|
||||
this.type = localType;
|
||||
type = localType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.MappingException;
|
||||
import org.hibernate.PropertyNotFoundException;
|
||||
import org.hibernate.Remove;
|
||||
import org.hibernate.boot.spi.BootstrapContext;
|
||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
|
@ -38,12 +37,9 @@ import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
|
|||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.resource.beans.internal.FallbackBeanInstanceProducer;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||
import org.hibernate.type.descriptor.ValueExtractor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.spi.CompositeTypeImplementor;
|
||||
import org.hibernate.usertype.CompositeUserType;
|
||||
|
||||
import static org.hibernate.internal.util.ReflectHelper.isRecord;
|
||||
|
||||
|
@ -68,13 +64,22 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
private final boolean isKey;
|
||||
private boolean hasNotNullProperty;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final CompositeUserType compositeUserType;
|
||||
|
||||
private EmbeddableValuedModelPart mappingModelPart;
|
||||
|
||||
public ComponentType(Component component, int[] originalPropertyOrder, MetadataBuildingContext buildingContext) {
|
||||
@Deprecated(forRemoval = true)
|
||||
public ComponentType(Component component, int[] originalPropertyOrder, MetadataBuildingContext context) {
|
||||
this( component, originalPropertyOrder );
|
||||
}
|
||||
|
||||
public ComponentType(Component component, int[] originalPropertyOrder) {
|
||||
this( component, originalPropertyOrder,
|
||||
component.getComponentClassName() != null
|
||||
&& !isRecord( component.getComponentClass() ) );
|
||||
}
|
||||
|
||||
public ComponentType(Component component, int[] originalPropertyOrder, boolean mutable) {
|
||||
this.componentClass = component.isDynamic() ? Map.class : component.getComponentClass();
|
||||
this.mutable = mutable;
|
||||
this.isAggregate = component.getAggregateColumn() != null;
|
||||
this.isKey = component.isKey();
|
||||
this.propertySpan = component.getPropertySpan();
|
||||
|
@ -97,23 +102,6 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
this.compositeUserType =
|
||||
component.getTypeName() == null ? null : createCompositeUserType( component, buildingContext );
|
||||
this.mutable = !isRecord( componentClass ) && ( compositeUserType == null || compositeUserType.isMutable() );
|
||||
}
|
||||
|
||||
private static CompositeUserType<?> createCompositeUserType(Component component, MetadataBuildingContext buildingContext) {
|
||||
final BootstrapContext bootstrapContext = buildingContext.getBootstrapContext();
|
||||
final Class<CompositeUserType<?>> customTypeClass =
|
||||
bootstrapContext.getClassLoaderAccess().classForName( component.getTypeName() );
|
||||
if ( buildingContext.getBuildingOptions().disallowExtensionsInCdi() ) {
|
||||
return FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( customTypeClass );
|
||||
}
|
||||
else {
|
||||
return bootstrapContext.getServiceRegistry().requireService( ManagedBeanRegistry.class )
|
||||
.getBean( customTypeClass ).getBeanInstance();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAggregate() {
|
||||
|
@ -178,9 +166,6 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
if ( x == y ) {
|
||||
return true;
|
||||
}
|
||||
if ( compositeUserType != null ) {
|
||||
return compositeUserType.equals( x, y );
|
||||
}
|
||||
// null value and empty component are considered equivalent
|
||||
for ( int i = 0; i < propertySpan; i++ ) {
|
||||
if ( !propertyTypes[i].isEqual( getPropertyValue( x, i ), getPropertyValue( y, i ) ) ) {
|
||||
|
@ -196,9 +181,6 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
if ( x == y ) {
|
||||
return true;
|
||||
}
|
||||
if ( compositeUserType != null ) {
|
||||
return compositeUserType.equals( x, y );
|
||||
}
|
||||
// null value and empty component are considered equivalent
|
||||
for ( int i = 0; i < propertySpan; i++ ) {
|
||||
if ( !propertyTypes[i].isEqual( getPropertyValue( x, i ), getPropertyValue( y, i ), factory ) ) {
|
||||
|
@ -242,9 +224,6 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
|
||||
@Override
|
||||
public int getHashCode(final Object x) {
|
||||
if ( compositeUserType != null ) {
|
||||
return compositeUserType.hashCode( x );
|
||||
}
|
||||
int result = 17;
|
||||
for ( int i = 0; i < propertySpan; i++ ) {
|
||||
final Object y = getPropertyValue( x, i );
|
||||
|
@ -258,9 +237,6 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
|
||||
@Override
|
||||
public int getHashCode(final Object x, final SessionFactoryImplementor factory) {
|
||||
if ( compositeUserType != null ) {
|
||||
return compositeUserType.hashCode( x );
|
||||
}
|
||||
int result = 17;
|
||||
for ( int i = 0; i < propertySpan; i++ ) {
|
||||
final Object y = getPropertyValue( x, i );
|
||||
|
@ -273,7 +249,8 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirty(final Object x, final Object y, final SharedSessionContractImplementor session) throws HibernateException {
|
||||
public boolean isDirty(final Object x, final Object y, final SharedSessionContractImplementor session)
|
||||
throws HibernateException {
|
||||
if ( x == y ) {
|
||||
return false;
|
||||
}
|
||||
|
@ -335,7 +312,8 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
final int len = propertyTypes[i].getColumnSpan( session.getFactory() );
|
||||
final boolean[] subcheckable = new boolean[len];
|
||||
System.arraycopy( checkable, loc, subcheckable, 0, len );
|
||||
if ( propertyTypes[i].isModified( getPropertyValue( old, i ), getPropertyValue( current, i ), subcheckable, session ) ) {
|
||||
if ( propertyTypes[i].isModified( getPropertyValue( old, i ),
|
||||
getPropertyValue( current, i ), subcheckable, session ) ) {
|
||||
return true;
|
||||
}
|
||||
loc += len;
|
||||
|
@ -493,9 +471,6 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
return null;
|
||||
}
|
||||
|
||||
if ( compositeUserType != null ) {
|
||||
return compositeUserType.deepCopy( component );
|
||||
}
|
||||
final Object[] values = getPropertyValues( component );
|
||||
for ( int i = 0; i < propertySpan; i++ ) {
|
||||
values[i] = propertyTypes[i].deepCopy( values[i], factory );
|
||||
|
@ -527,20 +502,10 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
if ( original == null ) {
|
||||
return null;
|
||||
}
|
||||
if ( compositeUserType != null ) {
|
||||
return compositeUserType.replace( original, target, owner );
|
||||
}
|
||||
//if ( original == target ) return target;
|
||||
|
||||
final Object[] originalValues = getPropertyValues( original );
|
||||
final Object[] resultValues;
|
||||
|
||||
if ( target == null ) {
|
||||
resultValues = new Object[originalValues.length];
|
||||
}
|
||||
else {
|
||||
resultValues = getPropertyValues( target );
|
||||
}
|
||||
final Object[] resultValues = target == null ? new Object[originalValues.length] : getPropertyValues( target );
|
||||
|
||||
final Object[] replacedValues = TypeHelper.replace(
|
||||
originalValues,
|
||||
|
@ -552,8 +517,7 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
);
|
||||
|
||||
if ( target == null ) {
|
||||
return instantiator()
|
||||
.instantiate( () -> replacedValues, session.getSessionFactory() );
|
||||
return instantiator().instantiate( () -> replacedValues, session.getSessionFactory() );
|
||||
}
|
||||
else {
|
||||
setPropertyValues( target, replacedValues );
|
||||
|
@ -576,9 +540,6 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
if ( original == null ) {
|
||||
return null;
|
||||
}
|
||||
if ( compositeUserType != null ) {
|
||||
return compositeUserType.replace( original, target, owner );
|
||||
}
|
||||
//if ( original == target ) return target;
|
||||
|
||||
final Object[] originalValues = getPropertyValues( original );
|
||||
|
@ -610,6 +571,8 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public CascadeStyle getCascadeStyle(int i) {
|
||||
return cascade[i];
|
||||
|
@ -626,9 +589,6 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
else if ( compositeUserType != null ) {
|
||||
return compositeUserType.disassemble( value );
|
||||
}
|
||||
else {
|
||||
final Object[] values = getPropertyValues( value );
|
||||
for ( int i = 0; i < propertyTypes.length; i++ ) {
|
||||
|
@ -639,13 +599,11 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public Serializable disassemble(Object value, SessionFactoryImplementor sessionFactory) throws HibernateException {
|
||||
public Serializable disassemble(Object value, SessionFactoryImplementor sessionFactory)
|
||||
throws HibernateException {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
else if ( compositeUserType != null ) {
|
||||
return compositeUserType.disassemble( value );
|
||||
}
|
||||
else {
|
||||
final Object[] values = getPropertyValues( value );
|
||||
for ( int i = 0; i < propertyTypes.length; i++ ) {
|
||||
|
@ -662,9 +620,6 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
if ( object == null ) {
|
||||
return null;
|
||||
}
|
||||
else if ( compositeUserType != null ) {
|
||||
return compositeUserType.assemble( object, owner );
|
||||
}
|
||||
else {
|
||||
final Object[] values = (Object[]) object;
|
||||
final Object[] assembled = new Object[values.length];
|
||||
|
@ -753,7 +708,8 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object extract(CallableStatement statement, int startIndex, SharedSessionContractImplementor session) throws SQLException {
|
||||
public Object extract(CallableStatement statement, int startIndex, SharedSessionContractImplementor session)
|
||||
throws SQLException {
|
||||
Object[] values;
|
||||
if ( isAggregate() ) {
|
||||
values = (Object[]) jdbcValueExtractor().extract( statement, startIndex, session );
|
||||
|
@ -842,8 +798,4 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
|||
}
|
||||
return mappingModelPart;
|
||||
}
|
||||
|
||||
public boolean isCompositeUserType() {
|
||||
return compositeUserType != null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
|||
/**
|
||||
* Represents a <em>composite</em> type, a type which itself has typed attributes.
|
||||
* <p>
|
||||
* For example, a type representing an {@linkplain jakarta.persistence.Embeddable embeddable}
|
||||
* class is a composite type.
|
||||
* For example, a type representing an {@linkplain jakarta.persistence.Embeddable embeddable} class
|
||||
* is a composite type, as is a type backed by a {@link org.hibernate.usertype.CompositeUserType}.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
@ -55,7 +55,8 @@ public interface CompositeType extends Type {
|
|||
*
|
||||
* @throws HibernateException Indicates a problem access the property values.
|
||||
*/
|
||||
Object[] getPropertyValues(Object component, SharedSessionContractImplementor session) throws HibernateException;
|
||||
Object[] getPropertyValues(Object component, SharedSessionContractImplementor session)
|
||||
throws HibernateException;
|
||||
|
||||
/**
|
||||
* Extract the values of the component properties from the given component instance without access to the
|
||||
|
@ -81,7 +82,8 @@ public interface CompositeType extends Type {
|
|||
*
|
||||
* @throws HibernateException Indicates a problem access the property value.
|
||||
*/
|
||||
Object getPropertyValue(Object component, int index, SharedSessionContractImplementor session) throws HibernateException;
|
||||
Object getPropertyValue(Object component, int index, SharedSessionContractImplementor session)
|
||||
throws HibernateException;
|
||||
|
||||
/**
|
||||
* Inject property values onto the given component instance
|
||||
|
@ -95,6 +97,24 @@ public interface CompositeType extends Type {
|
|||
*/
|
||||
void setPropertyValues(Object component, Object[] values) throws HibernateException;
|
||||
|
||||
/**
|
||||
* Inject property values onto the given component instance, or return a new
|
||||
* instance with the given property values.
|
||||
*
|
||||
* @param component The component instance
|
||||
* @param values The values to inject
|
||||
* @return A new instance is necessary
|
||||
*
|
||||
* @throws HibernateException Indicates an issue performing the injection
|
||||
*
|
||||
* @since 6.3
|
||||
*/
|
||||
default Object replacePropertyValues(Object component, Object[] values, SharedSessionContractImplementor session)
|
||||
throws HibernateException {
|
||||
setPropertyValues( component, values );
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the cascade style of the indicated component property.
|
||||
*
|
||||
|
|
|
@ -18,10 +18,16 @@ import org.hibernate.property.access.spi.Getter;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public class EmbeddedComponentType extends ComponentType {
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public EmbeddedComponentType(Component component, int[] originalPropertyOrder, MetadataBuildingContext buildingContext) {
|
||||
super( component, originalPropertyOrder, buildingContext );
|
||||
}
|
||||
|
||||
public EmbeddedComponentType(Component component, int[] originalPropertyOrder) {
|
||||
super( component, originalPropertyOrder );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmbedded() {
|
||||
return true;
|
||||
|
|
|
@ -11,7 +11,6 @@ import java.util.Map;
|
|||
import org.hibernate.Internal;
|
||||
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
|
||||
|
||||
|
@ -195,34 +194,17 @@ public class TypeHelper {
|
|||
if ( type.isComponentType() ) {
|
||||
final CompositeType compositeType = (CompositeType) type;
|
||||
// need to extract the component values and check for subtype replacements...
|
||||
final Type[] subtypes = compositeType.getSubtypes();
|
||||
final Object[] origComponentValues = currentOriginal == null
|
||||
? new Object[subtypes.length]
|
||||
: compositeType.getPropertyValues( currentOriginal, session );
|
||||
final Object[] targetComponentValues = target[i] == null
|
||||
? new Object[subtypes.length]
|
||||
: compositeType.getPropertyValues( target[i], session );
|
||||
final Object[] objects = replaceAssociations(
|
||||
origComponentValues,
|
||||
targetComponentValues,
|
||||
subtypes,
|
||||
final Object[] objects =
|
||||
replaceCompositeAssociations(
|
||||
session,
|
||||
null,
|
||||
copyCache,
|
||||
foreignKeyDirection
|
||||
foreignKeyDirection,
|
||||
target[i],
|
||||
currentOriginal,
|
||||
compositeType
|
||||
);
|
||||
if ( target[i] != null && compositeType instanceof ComponentType ) {
|
||||
final ComponentType componentType = (ComponentType) compositeType;
|
||||
if ( componentType.isCompositeUserType() ) {
|
||||
final EmbeddableInstantiator instantiator = ( (ComponentType) compositeType ).getMappingModelPart()
|
||||
.getEmbeddableTypeDescriptor()
|
||||
.getRepresentationStrategy()
|
||||
.getInstantiator();
|
||||
target[i] = instantiator.instantiate( () -> objects, session.getSessionFactory() );
|
||||
}
|
||||
else {
|
||||
compositeType.setPropertyValues( target[i], objects );
|
||||
}
|
||||
if ( target[i] != null ) {
|
||||
target[i] = compositeType.replacePropertyValues( target[i], objects, session );
|
||||
}
|
||||
copied[i] = target[i];
|
||||
}
|
||||
|
@ -237,4 +219,26 @@ public class TypeHelper {
|
|||
return copied;
|
||||
}
|
||||
|
||||
private static Object[] replaceCompositeAssociations(
|
||||
SharedSessionContractImplementor session,
|
||||
Map<Object, Object> copyCache,
|
||||
ForeignKeyDirection foreignKeyDirection,
|
||||
Object target, Object currentOriginal,
|
||||
CompositeType compositeType) {
|
||||
final Type[] subtypes = compositeType.getSubtypes();
|
||||
return replaceAssociations(
|
||||
currentOriginal == null
|
||||
? new Object[subtypes.length]
|
||||
: compositeType.getPropertyValues( currentOriginal, session ),
|
||||
target == null
|
||||
? new Object[subtypes.length]
|
||||
: compositeType.getPropertyValues( target, session ),
|
||||
subtypes,
|
||||
session,
|
||||
null,
|
||||
copyCache,
|
||||
foreignKeyDirection
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.type;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.usertype.CompositeUserType;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Handles {@link CompositeUserType}s.
|
||||
*
|
||||
* @author Gavin King
|
||||
*
|
||||
* @since 6.3
|
||||
*/
|
||||
public class UserComponentType<T> extends ComponentType {
|
||||
|
||||
private final CompositeUserType<T> compositeUserType;
|
||||
|
||||
public UserComponentType(
|
||||
Component component,
|
||||
int[] originalPropertyOrder,
|
||||
CompositeUserType<T> compositeUserType) {
|
||||
super( component, originalPropertyOrder, compositeUserType.isMutable() );
|
||||
this.compositeUserType = compositeUserType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEqual(Object x, Object y) throws HibernateException {
|
||||
return x==y || compositeUserType.equals( (T) x, (T) y );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEqual(Object x, Object y, SessionFactoryImplementor factory)
|
||||
throws HibernateException {
|
||||
return isEqual( x, y );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHashCode(Object x) {
|
||||
return compositeUserType.hashCode( (T) x );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHashCode(Object x, SessionFactoryImplementor factory) {
|
||||
return getHashCode( x );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object deepCopy(Object component, SessionFactoryImplementor factory) {
|
||||
return component == null ? null : compositeUserType.deepCopy( (T) component );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object replace(Object original, Object target, SharedSessionContractImplementor session, Object owner, Map<Object, Object> copyCache) {
|
||||
return original == null || !isMutable() ? original : compositeUserType.replace( (T) original, (T) target, owner );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object replace(Object original, Object target, SharedSessionContractImplementor session, Object owner, Map<Object, Object> copyCache, ForeignKeyDirection foreignKeyDirection) {
|
||||
return replace( original, target, session, owner, copyCache );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable disassemble(Object value, SessionFactoryImplementor sessionFactory)
|
||||
throws HibernateException {
|
||||
return value == null ? null : compositeUserType.disassemble( (T) value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable disassemble(Object value, SharedSessionContractImplementor session, Object owner)
|
||||
throws HibernateException {
|
||||
return disassemble( value, session.getFactory() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object assemble(Serializable object, SharedSessionContractImplementor session, Object owner)
|
||||
throws HibernateException {
|
||||
return object == null ? null : compositeUserType.assemble( object, owner );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object replacePropertyValues(Object component, Object[] values, SharedSessionContractImplementor session)
|
||||
throws HibernateException {
|
||||
return getMappingModelPart()
|
||||
.getEmbeddableTypeDescriptor()
|
||||
.getRepresentationStrategy()
|
||||
.getInstantiator().instantiate( () -> values, session.getSessionFactory() );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue