Introduce `VirtualIdEmbeddable` and `IdClassEmbeddable` + instantiators
Move all component instantiations to use the new mapping model EmbeddableInstantiator Still need to - integrate embedded forms. `VirtualIdEmbeddable` does not really need it as it can use the id-mapping itself as the embedded form. But `IdClassEmbedded` should really be integrated - integrate `VirtualKeyEmbeddable` and `VirtualKeyEmbedded` for use as inverse composite fks - share `#finishInit` handling for `EmbeddableMappingType`, `VirtualIdEmbeddable` and `IdClassEmbeddable` - ability to use the containing composite owner as the parent of a composite (legacy behavior is to always use the "first" entity - clean up ComponentType, esp wrt its use of ComponentTuplizer
This commit is contained in:
parent
5b44aa5d44
commit
eb5afb0427
|
@ -5,6 +5,7 @@
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.tuple.component;
|
package org.hibernate.tuple.component;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
@ -13,7 +14,6 @@ import org.hibernate.mapping.Component;
|
||||||
import org.hibernate.mapping.Property;
|
import org.hibernate.mapping.Property;
|
||||||
import org.hibernate.property.access.spi.Getter;
|
import org.hibernate.property.access.spi.Getter;
|
||||||
import org.hibernate.property.access.spi.Setter;
|
import org.hibernate.property.access.spi.Setter;
|
||||||
import org.hibernate.tuple.Instantiator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support for tuplizers relating to components.
|
* Support for tuplizers relating to components.
|
||||||
|
@ -25,10 +25,8 @@ public abstract class AbstractComponentTuplizer implements ComponentTuplizer {
|
||||||
protected final Getter[] getters;
|
protected final Getter[] getters;
|
||||||
protected final Setter[] setters;
|
protected final Setter[] setters;
|
||||||
protected final int propertySpan;
|
protected final int propertySpan;
|
||||||
protected final Instantiator instantiator;
|
|
||||||
protected final boolean hasCustomAccessors;
|
protected final boolean hasCustomAccessors;
|
||||||
|
|
||||||
protected abstract Instantiator buildInstantiator(Component component);
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -51,7 +49,6 @@ public abstract class AbstractComponentTuplizer implements ComponentTuplizer {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
hasCustomAccessors = foundCustomAccessor;
|
hasCustomAccessors = foundCustomAccessor;
|
||||||
instantiator = buildInstantiator( component );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getPropertyValue(Object component, int i) throws HibernateException {
|
public Object getPropertyValue(Object component, int i) throws HibernateException {
|
||||||
|
@ -72,13 +69,6 @@ public abstract class AbstractComponentTuplizer implements ComponentTuplizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method does not populate the component parent
|
|
||||||
*/
|
|
||||||
public Object instantiate() throws HibernateException {
|
|
||||||
return instantiator.instantiate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMethodOf(Method method) {
|
public boolean isMethodOf(Method method) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,13 +35,6 @@ public interface ComponentTuplizer extends Tuplizer, Serializable {
|
||||||
*/
|
*/
|
||||||
public boolean isMethodOf(Method method);
|
public boolean isMethodOf(Method method);
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a new, empty entity.
|
|
||||||
*
|
|
||||||
* @return The new, empty entity instance.
|
|
||||||
*/
|
|
||||||
public Object instantiate();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the current values contained on the given entity.
|
* Extract the current values contained on the given entity.
|
||||||
*
|
*
|
||||||
|
|
|
@ -12,8 +12,6 @@ import org.hibernate.mapping.Property;
|
||||||
import org.hibernate.property.access.internal.PropertyAccessStrategyMapImpl;
|
import org.hibernate.property.access.internal.PropertyAccessStrategyMapImpl;
|
||||||
import org.hibernate.property.access.spi.Getter;
|
import org.hibernate.property.access.spi.Getter;
|
||||||
import org.hibernate.property.access.spi.Setter;
|
import org.hibernate.property.access.spi.Setter;
|
||||||
import org.hibernate.tuple.DynamicMapInstantiator;
|
|
||||||
import org.hibernate.tuple.Instantiator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link ComponentTuplizer} specific to the dynamic-map entity mode.
|
* A {@link ComponentTuplizer} specific to the dynamic-map entity mode.
|
||||||
|
@ -27,10 +25,6 @@ public class DynamicMapComponentTuplizer extends AbstractComponentTuplizer {
|
||||||
return Map.class;
|
return Map.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Instantiator buildInstantiator(Component component) {
|
|
||||||
return new DynamicMapInstantiator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DynamicMapComponentTuplizer(Component component) {
|
public DynamicMapComponentTuplizer(Component component) {
|
||||||
super(component);
|
super(component);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ import org.hibernate.bytecode.spi.BytecodeProvider;
|
||||||
import org.hibernate.bytecode.spi.ProxyFactoryFactory;
|
import org.hibernate.bytecode.spi.ProxyFactoryFactory;
|
||||||
import org.hibernate.bytecode.spi.ReflectionOptimizer;
|
import org.hibernate.bytecode.spi.ReflectionOptimizer;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
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.property.access.internal.PropertyAccessStrategyBackRefImpl;
|
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
|
||||||
|
@ -24,7 +23,6 @@ import org.hibernate.property.access.spi.Getter;
|
||||||
import org.hibernate.property.access.spi.PropertyAccess;
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
import org.hibernate.property.access.spi.Setter;
|
import org.hibernate.property.access.spi.Setter;
|
||||||
import org.hibernate.tuple.Instantiator;
|
import org.hibernate.tuple.Instantiator;
|
||||||
import org.hibernate.tuple.PojoInstantiator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link ComponentTuplizer} specific to the pojo entity mode.
|
* A {@link ComponentTuplizer} specific to the pojo entity mode.
|
||||||
|
@ -110,19 +108,6 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Instantiator buildInstantiator(Component component) {
|
|
||||||
if ( component.isEmbedded() && ReflectHelper.isAbstractClass( this.componentClass ) ) {
|
|
||||||
ProxyFactoryFactory proxyFactoryFactory = component.getServiceRegistry().getService( ProxyFactoryFactory.class );
|
|
||||||
return new ProxiedInstantiator( this.componentClass, proxyFactoryFactory );
|
|
||||||
}
|
|
||||||
if ( optimizer == null ) {
|
|
||||||
return new PojoInstantiator( this.componentClass, null );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return new PojoInstantiator( this.componentClass, optimizer.getInstantiationOptimizer() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Getter buildGetter(Component component, Property prop) {
|
protected Getter buildGetter(Component component, Property prop) {
|
||||||
return prop.getGetter( this.componentClass );
|
return prop.getGetter( this.componentClass );
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
|
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
|
||||||
|
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||||
import org.hibernate.property.access.spi.PropertyAccess;
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
import org.hibernate.tuple.StandardProperty;
|
import org.hibernate.tuple.StandardProperty;
|
||||||
import org.hibernate.tuple.ValueGeneration;
|
import org.hibernate.tuple.ValueGeneration;
|
||||||
|
@ -466,19 +467,20 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object deepCopy(Object component, SessionFactoryImplementor factory)
|
public Object deepCopy(Object component, SessionFactoryImplementor factory) {
|
||||||
throws HibernateException {
|
|
||||||
if ( component == null ) {
|
if ( component == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object[] values = getPropertyValues( component );
|
final Object[] values = getPropertyValues( component );
|
||||||
for ( int i = 0; i < propertySpan; i++ ) {
|
for ( int i = 0; i < propertySpan; i++ ) {
|
||||||
values[i] = propertyTypes[i].deepCopy( values[i], factory );
|
values[i] = propertyTypes[i].deepCopy( values[i], factory );
|
||||||
}
|
}
|
||||||
|
|
||||||
Object result = instantiate();
|
final EmbeddableInstantiator instantiator = mappingModelPart.getEmbeddableTypeDescriptor()
|
||||||
setPropertyValues( result, values );
|
.getRepresentationStrategy()
|
||||||
|
.getInstantiator();
|
||||||
|
Object result = instantiator.instantiate( () -> values, factory );
|
||||||
|
|
||||||
//not absolutely necessary, but helps for some
|
//not absolutely necessary, but helps for some
|
||||||
//equals()/hashCode() implementations
|
//equals()/hashCode() implementations
|
||||||
|
@ -496,29 +498,42 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
||||||
Object target,
|
Object target,
|
||||||
SharedSessionContractImplementor session,
|
SharedSessionContractImplementor session,
|
||||||
Object owner,
|
Object owner,
|
||||||
Map copyCache)
|
Map copyCache) {
|
||||||
throws HibernateException {
|
|
||||||
|
|
||||||
if ( original == null ) {
|
if ( original == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
//if ( original == target ) return target;
|
//if ( original == target ) return target;
|
||||||
|
|
||||||
final Object result = target == null
|
final Object[] originalValues = getPropertyValues( original );
|
||||||
? instantiate( owner, session )
|
final Object[] resultValues;
|
||||||
: target;
|
|
||||||
|
|
||||||
Object[] values = TypeHelper.replace(
|
if ( target == null ) {
|
||||||
getPropertyValues( original ),
|
resultValues = new Object[originalValues.length];
|
||||||
getPropertyValues( result ),
|
}
|
||||||
|
else {
|
||||||
|
resultValues = getPropertyValues( target );
|
||||||
|
}
|
||||||
|
|
||||||
|
final Object[] replacedValues = TypeHelper.replace(
|
||||||
|
originalValues,
|
||||||
|
resultValues,
|
||||||
propertyTypes,
|
propertyTypes,
|
||||||
session,
|
session,
|
||||||
owner,
|
owner,
|
||||||
copyCache
|
copyCache
|
||||||
);
|
);
|
||||||
|
|
||||||
setPropertyValues( result, values );
|
if ( target == null ) {
|
||||||
return result;
|
final EmbeddableInstantiator instantiator = mappingModelPart.getEmbeddableTypeDescriptor()
|
||||||
|
.getRepresentationStrategy()
|
||||||
|
.getInstantiator();
|
||||||
|
return instantiator.instantiate( () -> replacedValues, session.getSessionFactory() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setPropertyValues( target, replacedValues );
|
||||||
|
return target;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -528,21 +543,27 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
||||||
SharedSessionContractImplementor session,
|
SharedSessionContractImplementor session,
|
||||||
Object owner,
|
Object owner,
|
||||||
Map copyCache,
|
Map copyCache,
|
||||||
ForeignKeyDirection foreignKeyDirection)
|
ForeignKeyDirection foreignKeyDirection) {
|
||||||
throws HibernateException {
|
|
||||||
|
|
||||||
if ( original == null ) {
|
if ( original == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
//if ( original == target ) return target;
|
//if ( original == target ) return target;
|
||||||
|
|
||||||
final Object result = target == null ?
|
|
||||||
instantiate( owner, session ) :
|
|
||||||
target;
|
|
||||||
|
|
||||||
Object[] values = TypeHelper.replace(
|
final Object[] originalValues = getPropertyValues( original );
|
||||||
getPropertyValues( original ),
|
final Object[] resultValues;
|
||||||
getPropertyValues( result ),
|
|
||||||
|
if ( target == null ) {
|
||||||
|
resultValues = new Object[originalValues.length];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resultValues = getPropertyValues( target );
|
||||||
|
}
|
||||||
|
|
||||||
|
final Object[] replacedValues = TypeHelper.replace(
|
||||||
|
originalValues,
|
||||||
|
resultValues,
|
||||||
propertyTypes,
|
propertyTypes,
|
||||||
session,
|
session,
|
||||||
owner,
|
owner,
|
||||||
|
@ -550,30 +571,16 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
||||||
foreignKeyDirection
|
foreignKeyDirection
|
||||||
);
|
);
|
||||||
|
|
||||||
setPropertyValues( result, values );
|
if ( target == null ) {
|
||||||
return result;
|
final EmbeddableInstantiator instantiator = mappingModelPart.getEmbeddableTypeDescriptor()
|
||||||
|
.getRepresentationStrategy()
|
||||||
|
.getInstantiator();
|
||||||
|
return instantiator.instantiate( () -> replacedValues, session.getSessionFactory() );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
/**
|
setPropertyValues( target, replacedValues );
|
||||||
* This method does not populate the component parent
|
return target;
|
||||||
*/
|
|
||||||
public Object instantiate() {
|
|
||||||
return componentTuplizer.instantiate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object instantiate(Object parent, SharedSessionContractImplementor session) {
|
|
||||||
Object result = instantiate();
|
|
||||||
|
|
||||||
final PropertyAccess parentAccess = mappingModelPart().getParentInjectionAttributePropertyAccess();
|
|
||||||
if ( parentAccess != null && parent != null ) {
|
|
||||||
parentAccess.getSetter().set(
|
|
||||||
result,
|
|
||||||
session.getPersistenceContextInternal().proxyFor( parent ),
|
|
||||||
session.getFactory()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -615,9 +622,11 @@ public class ComponentType extends AbstractType implements CompositeTypeImplemen
|
||||||
for ( int i = 0; i < propertyTypes.length; i++ ) {
|
for ( int i = 0; i < propertyTypes.length; i++ ) {
|
||||||
assembled[i] = propertyTypes[i].assemble( (Serializable) values[i], session, owner );
|
assembled[i] = propertyTypes[i].assemble( (Serializable) values[i], session, owner );
|
||||||
}
|
}
|
||||||
Object result = instantiate( owner, session );
|
|
||||||
setPropertyValues( result, assembled );
|
final EmbeddableInstantiator instantiator = mappingModelPart.getEmbeddableTypeDescriptor()
|
||||||
return result;
|
.getRepresentationStrategy()
|
||||||
|
.getInstantiator();
|
||||||
|
return instantiator.instantiate( () -> assembled, session.getFactory() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,6 @@ package org.hibernate.type;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
|
||||||
import org.hibernate.tuple.component.ComponentMetamodel;
|
import org.hibernate.tuple.component.ComponentMetamodel;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
@ -28,15 +26,4 @@ public class EmbeddedComponentType extends ComponentType {
|
||||||
public boolean isMethodOf(Method method) {
|
public boolean isMethodOf(Method method) {
|
||||||
return componentTuplizer.isMethodOf( method );
|
return componentTuplizer.isMethodOf( method );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object instantiate(Object parent, SharedSessionContractImplementor session) throws HibernateException {
|
|
||||||
final boolean useParent = parent != null &&
|
|
||||||
//TODO: Yuck! This is not quite good enough, it's a quick
|
|
||||||
//hack around the problem of having a to-one association
|
|
||||||
//that refers to an embedded component:
|
|
||||||
super.getReturnedClass().isInstance( parent );
|
|
||||||
|
|
||||||
return useParent ? parent : super.instantiate( parent, session );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,43 +8,40 @@ package org.hibernate.orm.test.component.proxy;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.boot.Metadata;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.boot.MetadataSources;
|
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||||
import org.hibernate.type.ComponentType;
|
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
|
||||||
|
import org.hibernate.type.spi.CompositeTypeImplementor;
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.junit.Test;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModelScope;
|
||||||
|
import org.hibernate.testing.orm.junit.NotImplementedYet;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Guillaume Smet
|
* @author Guillaume Smet
|
||||||
* @author Oliver Libutzki
|
* @author Oliver Libutzki
|
||||||
*/
|
*/
|
||||||
public class ComponentBasicProxyTest extends BaseEntityManagerFunctionalTestCase {
|
@DomainModel( annotatedClasses = { Person.class, Adult.class } )
|
||||||
|
@SessionFactory
|
||||||
@Override
|
public class ComponentBasicProxyTest {
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
|
||||||
return new Class[]{
|
|
||||||
Person.class, Adult.class
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestForIssue(jiraKey = "HHH-12786")
|
@TestForIssue(jiraKey = "HHH-12786")
|
||||||
public void testBasicProxyingWithProtectedMethodCalledInConstructor() {
|
public void testBasicProxyingWithProtectedMethodCalledInConstructor(SessionFactoryScope scope) {
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
scope.inTransaction( (entityManager) -> {
|
||||||
Adult adult = new Adult();
|
Adult adult = new Adult();
|
||||||
adult.setName( "Arjun Kumar" );
|
adult.setName( "Arjun Kumar" );
|
||||||
entityManager.persist( adult );
|
entityManager.persist( adult );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
scope.inTransaction( (entityManager) -> {
|
||||||
List<Adult> adultsCalledArjun = entityManager
|
List<Adult> adultsCalledArjun = entityManager
|
||||||
.createQuery( "SELECT a from Adult a WHERE a.name = :name", Adult.class )
|
.createQuery( "SELECT a from Adult a WHERE a.name = :name", Adult.class )
|
||||||
.setParameter( "name", "Arjun Kumar" ).getResultList();
|
.setParameter( "name", "Arjun Kumar" ).getResultList();
|
||||||
|
@ -55,25 +52,18 @@ public class ComponentBasicProxyTest extends BaseEntityManagerFunctionalTestCase
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestForIssue(jiraKey = "HHH-12791")
|
@TestForIssue(jiraKey = "HHH-12791")
|
||||||
public void testOnlyOneProxyClassGenerated() {
|
public void testOnlyOneProxyClassGenerated(DomainModelScope domainModelScope, SessionFactoryScope sfScope) {
|
||||||
StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().build();
|
final SessionFactoryImplementor sessionFactory = sfScope.getSessionFactory();
|
||||||
|
|
||||||
try {
|
final PersistentClass personDescriptor = domainModelScope.getDomainModel().getEntityBinding( Person.class.getName() );
|
||||||
Metadata metadata = new MetadataSources( ssr ).addAnnotatedClass( Person.class )
|
final CompositeTypeImplementor componentType = (CompositeTypeImplementor) personDescriptor.getIdentifierMapper().getType();
|
||||||
.getMetadataBuilder()
|
final EmbeddableValuedModelPart embedded = componentType.getMappingModelPart();
|
||||||
.build();
|
final EmbeddableInstantiator instantiator = embedded.getEmbeddableTypeDescriptor()
|
||||||
PersistentClass persistentClass = metadata.getEntityBinding( Person.class.getName() );
|
.getRepresentationStrategy()
|
||||||
|
.getInstantiator();
|
||||||
|
|
||||||
ComponentType componentType1 = (ComponentType) persistentClass.getIdentifierMapper().getType();
|
final Object instance1 = instantiator.instantiate( null, sessionFactory );
|
||||||
Object instance1 = componentType1.instantiate();
|
final Object instance2 = instantiator.instantiate( null, sessionFactory );
|
||||||
|
assertThat( instance1.getClass() ).isEqualTo( instance2.getClass() );
|
||||||
ComponentType componentType2 = (ComponentType) persistentClass.getIdentifierMapper().getType();
|
|
||||||
Object instance2 = componentType2.instantiate();
|
|
||||||
|
|
||||||
assertEquals( instance1.getClass(), instance2.getClass() );
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
StandardServiceRegistryBuilder.destroy( ssr );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue