Fix use EmbeddedIdentifier instance as Entity

This commit is contained in:
Andrea Boriero 2021-05-07 12:48:06 +02:00
parent 4e9b8c0c34
commit 0ecd66fd46
4 changed files with 36 additions and 67 deletions

View File

@ -18,17 +18,9 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
*/
public class EmbeddableAssembler implements DomainResultAssembler {
protected final EmbeddableInitializer initializer;
private final boolean containingClass;
public EmbeddableAssembler(EmbeddableInitializer initializer) {
this.initializer = initializer;
if ( initializer instanceof AbstractCompositeIdentifierMapping ) {
containingClass = ( (AbstractCompositeIdentifierMapping) initializer.getInitializedPart() )
.hasContainingClass();
}
else {
containingClass = true;
}
}
@Override
@ -36,10 +28,6 @@ public class EmbeddableAssembler implements DomainResultAssembler {
return initializer.getInitializedPart().getJavaTypeDescriptor();
}
public boolean hasContainingClass() {
return containingClass;
}
@Override
public Object assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options) {
initializer.resolveKey( rowProcessingState );

View File

@ -74,7 +74,6 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
private final List<Initializer> identifierInitializers = new ArrayList<>();
private final DomainResultAssembler identifierAssembler;
private final boolean embeddableIdentifierWithNoContainingClass;
private final DomainResultAssembler discriminatorAssembler;
private final DomainResultAssembler versionAssembler;
private final DomainResultAssembler<Object> rowIdAssembler;
@ -161,8 +160,6 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
this.identifierAssembler = null;
}
embeddableIdentifierWithNoContainingClass = hasEmbeddableIdentifierWithNoContainingClass( identifierAssembler );
if ( discriminatorResult != null ) {
discriminatorAssembler = discriminatorResult.createResultAssembler( creationState );
}
@ -214,13 +211,6 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
);
}
protected final boolean hasEmbeddableIdentifierWithNoContainingClass(DomainResultAssembler identifierAssembler) {
if ( identifierAssembler instanceof EmbeddableAssembler ) {
return !( (EmbeddableAssembler) identifierAssembler ).hasContainingClass();
}
return false;
}
@Override
public ModelPart getInitializedPart() {
return referencedModelPart;
@ -369,18 +359,8 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
final JdbcValuesSourceProcessingState jdbcValuesSourceProcessingState = rowProcessingState.getJdbcValuesSourceProcessingState();
final SharedSessionContractImplementor session = jdbcValuesSourceProcessingState.getSession();
Object id;
// 1) resolve the hydrated identifier value(s) into its identifier representation
if ( identifierAssembler == null ) {
id = jdbcValuesSourceProcessingState.getProcessingOptions().getEffectiveOptionalId();
}
else {
initializeIdentifier( rowProcessingState );
id = identifierAssembler.assemble(
rowProcessingState,
jdbcValuesSourceProcessingState.getProcessingOptions()
);
}
final Object id = initializeIdentifier( rowProcessingState, jdbcValuesSourceProcessingState );
if ( id == null ) {
missing = true;
@ -388,10 +368,6 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
return;
}
if ( embeddableIdentifierWithNoContainingClass ) {
entityInstance = id;
}
// 2) build the EntityKey
this.entityKey = new EntityKey( id, concreteDescriptor );
@ -407,6 +383,28 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
}
}
private Object initializeIdentifier(
RowProcessingState rowProcessingState,
JdbcValuesSourceProcessingState jdbcValuesSourceProcessingState) {
final Object id = jdbcValuesSourceProcessingState.getProcessingOptions().getEffectiveOptionalId();
final boolean useEmbeddedIdentifierInstanceAsEntity = id != null && id.getClass()
.equals( concreteDescriptor.getJavaTypeDescriptor().getJavaType() );
if ( useEmbeddedIdentifierInstanceAsEntity ) {
entityInstance = id;
return id;
}
if ( identifierAssembler == null ) {
return id;
}
initializeIdentifier( rowProcessingState );
return identifierAssembler.assemble(
rowProcessingState,
jdbcValuesSourceProcessingState.getProcessingOptions()
);
}
@SuppressWarnings("WeakerAccess")
protected void initializeIdentifier(RowProcessingState rowProcessingState) {
if ( EntityLoadingLogger.TRACE_ENABLED ) {
@ -417,11 +415,9 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
);
}
if ( !embeddableIdentifierWithNoContainingClass ) {
identifierInitializers.forEach( initializer -> initializer.resolveKey( rowProcessingState ) );
identifierInitializers.forEach( initializer -> initializer.resolveInstance( rowProcessingState ) );
identifierInitializers.forEach( initializer -> initializer.initializeInstance( rowProcessingState ) );
}
identifierInitializers.forEach( initializer -> initializer.resolveKey( rowProcessingState ) );
identifierInitializers.forEach( initializer -> initializer.resolveInstance( rowProcessingState ) );
identifierInitializers.forEach( initializer -> initializer.initializeInstance( rowProcessingState ) );
if ( EntityLoadingLogger.TRACE_ENABLED ) {
EntityLoadingLogger.LOGGER.tracef(

View File

@ -1,25 +0,0 @@
<!--
~ 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>.
-->
<hibernate-mapping package="org.hibernate.orm.test.onetoone.basic" default-access="field">
<class name="Parent">
<id name="id"/>
<one-to-one name="child" cascade="all" constrained="false" outer-join="false" lazy="proxy"/>
</class>
<class name="Child">
<id name=""
</class>
<class name="Address">
<id name="entityName"/>
<property name="street"/>
<property name="state"/>
<property name="zip"/>
</class>
</hibernate-mapping>

View File

@ -163,6 +163,16 @@ public class OneToOneFormulaTest extends BaseSessionFactoryFunctionalTest {
assertNull( p.getMailingAddress() );
} );
inTransaction( session -> {
Address a = (Address) session.createQuery( "from Address" ).uniqueResult();
Person person = a.getPerson();
assertNotNull( person );
assertTrue( Hibernate.isInitialized( person.getAddress() ) );
assertTrue( Hibernate.isInitialized( person.getMailingAddress() ) );
assertNull( person.getMailingAddress() );
} );
}