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