Introduce `VirtualIdEmbeddable` and `IdClassEmbeddable` + instantiators
EmbeddableInitializer fully uses EmbeddableInstantiator and value injection Still need to - integrate EmbeddableInstantiator work (ComponentType/ComponentTuplizer) - 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
This commit is contained in:
parent
82d884d65c
commit
a9fce4b69d
|
@ -67,6 +67,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
// and every row
|
||||
private final Object[] resolvedValues;
|
||||
private Boolean allValuesNull;
|
||||
private Boolean stateInjected;
|
||||
private Object compositeInstance;
|
||||
|
||||
|
||||
|
@ -155,6 +156,8 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
navigablePath
|
||||
);
|
||||
|
||||
stateInjected = false;
|
||||
|
||||
extractRowState( processingState );
|
||||
prepareCompositeInstance( processingState );
|
||||
handleParentInjection( processingState );
|
||||
|
@ -165,9 +168,10 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
if ( compositeInstance instanceof HibernateProxy ) {
|
||||
final Initializer parentInitializer = processingState.resolveInitializer( navigablePath.getParent() );
|
||||
if ( parentInitializer != this ) {
|
||||
( (FetchParentAccess) parentInitializer ).registerResolutionListener(
|
||||
(entity) -> representationEmbeddable.setPropertyValues( entity, resolvedValues )
|
||||
);
|
||||
( (FetchParentAccess) parentInitializer ).registerResolutionListener( (entity) -> {
|
||||
representationEmbeddable.setPropertyValues( entity, resolvedValues );
|
||||
stateInjected = true;
|
||||
} );
|
||||
}
|
||||
else {
|
||||
// At this point, createEmptyCompositesEnabled is always true, so we generate
|
||||
|
@ -182,13 +186,15 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
final Object target = representationStrategy
|
||||
.getInstantiator()
|
||||
.instantiate( valuesAccess, sessionFactory);
|
||||
stateInjected = true;
|
||||
( (HibernateProxy) compositeInstance ).getHibernateLazyInitializer().setImplementation( target );
|
||||
}
|
||||
}
|
||||
else if ( allValuesNull == FALSE ) {
|
||||
else if ( allValuesNull == FALSE && stateInjected != TRUE ) {
|
||||
// todo (6.0) : i think this is still called for cases where
|
||||
// we have already done the "ctor injection"
|
||||
representationEmbeddable.setPropertyValues( compositeInstance, resolvedValues );
|
||||
stateInjected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -290,8 +296,8 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
final Supplier<Object[]> valuesAccess = allValuesNull == TRUE
|
||||
? null
|
||||
: () -> resolvedValues;
|
||||
|
||||
final Object instance = representationStrategy.getInstantiator().instantiate( valuesAccess, sessionFactory );
|
||||
stateInjected = true;
|
||||
|
||||
EmbeddableLoadingLogger.INSTANCE.debugf( "Created composite instance [%s] : %s", navigablePath, instance );
|
||||
|
||||
|
@ -299,12 +305,6 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
}
|
||||
|
||||
private void handleParentInjection(RowProcessingState processingState) {
|
||||
final PropertyAccess parentInjectionAccess = embedded.getParentInjectionAttributePropertyAccess();
|
||||
if ( parentInjectionAccess == null ) {
|
||||
// embeddable defined no parent injection
|
||||
return;
|
||||
}
|
||||
|
||||
// todo (6.0) : should we initialize the composite instance if we get here and it is null (not NULL_MARKER)?
|
||||
|
||||
// we want to avoid injection for `NULL_MARKER`
|
||||
|
@ -316,6 +316,12 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
return;
|
||||
}
|
||||
|
||||
final PropertyAccess parentInjectionAccess = embedded.getParentInjectionAttributePropertyAccess();
|
||||
if ( parentInjectionAccess == null ) {
|
||||
// embeddable defined no parent injection
|
||||
return;
|
||||
}
|
||||
|
||||
final Object parent = determineParentInstance( processingState );
|
||||
if ( parent == null ) {
|
||||
EmbeddableLoadingLogger.INSTANCE.debugf(
|
||||
|
@ -332,11 +338,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
compositeInstance
|
||||
);
|
||||
|
||||
parentInjectionAccess.getSetter().set(
|
||||
compositeInstance,
|
||||
parent,
|
||||
sessionFactory
|
||||
);
|
||||
parentInjectionAccess.getSetter().set( compositeInstance, parent, sessionFactory );
|
||||
}
|
||||
|
||||
private Object determineParentInstance(RowProcessingState processingState) {
|
||||
|
@ -387,6 +389,8 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
public void finishUpRow(RowProcessingState rowProcessingState) {
|
||||
compositeInstance = null;
|
||||
allValuesNull = null;
|
||||
stateInjected = null;
|
||||
|
||||
clearResolutionListeners();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue