Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3239,42 +3239,49 @@ private void bindManyToManyFilters(
}

for ( var filterSource : elementSource.getFilterSources() ) {
if ( filterSource.getName() == null ) {
if ( BOOT_LOGGER.isTraceEnabled() ) {
BOOT_LOGGER.tracef(
"Encountered filter with no name associated with many-to-many [%s]; skipping",
getPluralAttributeSource().getAttributeRole().getFullPath()
);
}
bindManyToManyFilter( mappingDocument, collectionBinding, filterSource );
}
}

private void bindManyToManyFilter(
MappingDocument mappingDocument, Collection collectionBinding, FilterSource filterSource) {
final String name = filterSource.getName();
if ( name == null ) {
if ( BOOT_LOGGER.isTraceEnabled() ) {
BOOT_LOGGER.tracef(
"Encountered filter with no name associated with many-to-many [%s]; skipping",
getPluralAttributeSource().getAttributeRole().getFullPath()
);
}
else {
if ( filterSource.getCondition() == null ) {
throw new MappingException(
String.format(
Locale.ENGLISH,
"No filter condition found for filter [%s] associated with many-to-many [%s]",
filterSource.getName(),
getPluralAttributeSource().getAttributeRole().getFullPath()
),
mappingDocument.getOrigin()
);
}
if ( BOOT_LOGGER.isTraceEnabled() ) {
BOOT_LOGGER.tracef(
"Applying many-to-many filter [%s] as [%s] to collection [%s]",
filterSource.getName(),
filterSource.getCondition(),
getPluralAttributeSource().getAttributeRole().getFullPath()
);
}
collectionBinding.addManyToManyFilter(
filterSource.getName(),
filterSource.getCondition(),
filterSource.shouldAutoInjectAliases(),
filterSource.getAliasToTableMap(),
filterSource.getAliasToEntityMap()
}
else {
final String condition = filterSource.getCondition();
if ( condition == null ) {
throw new MappingException(
String.format(
Locale.ENGLISH,
"No filter condition found for filter [%s] associated with many-to-many [%s]",
name,
getPluralAttributeSource().getAttributeRole().getFullPath()
),
mappingDocument.getOrigin()
);
}
if ( BOOT_LOGGER.isTraceEnabled() ) {
BOOT_LOGGER.tracef(
"Applying many-to-many filter [%s] as [%s] to collection [%s]",
name,
condition,
getPluralAttributeSource().getAttributeRole().getFullPath()
);
}
collectionBinding.addManyToManyFilter(
name,
condition,
filterSource.shouldAutoInjectAliases(),
filterSource.getAliasToTableMap(),
filterSource.getAliasToEntityMap()
);
}
}

Expand Down Expand Up @@ -3451,10 +3458,9 @@ protected void createBackReferences() {
&& !collectionBinding.isInverse()
&& !indexIsFormula ) {
final var oneToMany = (OneToMany) collectionBinding.getElement();
final String entityName = oneToMany.getReferencedEntityName();
final var referenced =
getMappingDocument().getMetadataCollector()
.getEntityBinding( entityName );
.getEntityBinding( oneToMany.getReferencedEntityName() );
final var backref = new IndexBackref();
backref.setName( '_' + collectionBinding.getOwnerEntityName()
+ "." + getPluralAttributeSource().getName() + "IndexBackref" );
Expand Down Expand Up @@ -3533,10 +3539,9 @@ private void createIndexBackRef(
&& !collectionBinding.getKey().isNullable()
&& !collectionBinding.isInverse() ) {
final var oneToMany = (OneToMany) collectionBinding.getElement();
final String entityName = oneToMany.getReferencedEntityName();
final var referenced =
mappingDocument.getMetadataCollector()
.getEntityBinding( entityName );
.getEntityBinding( oneToMany.getReferencedEntityName() );
final var backref = new IndexBackref();
backref.setName( '_' + collectionBinding.getOwnerEntityName()
+ "." + pluralAttributeSource.getName() + "IndexBackref" );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,28 +32,26 @@ public interface InheritanceChecker {
* Should the given property be included in the owner's base fetch group?
*/
public static boolean includeInBaseFetchGroup(
Property bootMapping,
Property property,
boolean isEnhanced,
InheritanceChecker inheritanceChecker,
boolean collectionsInDefaultFetchGroupEnabled) {
final var value = bootMapping.getValue();

if ( ! isEnhanced ) {
if ( value instanceof ToOne toOne ) {
if ( toOne.isUnwrapProxy() ) {
BYTECODE_INTERCEPTOR_LOGGER.toOneLazyNoProxyButNotEnhanced(
bootMapping.getPersistentClass().getEntityName(),
bootMapping.getName()
);
}
final var value = property.getValue();

if ( !isEnhanced ) {
if ( value instanceof ToOne toOne && toOne.isUnwrapProxy() ) {
BYTECODE_INTERCEPTOR_LOGGER.toOneLazyNoProxyButNotEnhanced(
property.getPersistentClass().getEntityName(),
property.getName()
);
}
return true;
}

// if we get here, we know the property owner is enhanced for laziness
//
// NOTE : we make the (potentially untrue) assumption here that
// if the owner is enhanced, then all classes are enhanced..
// NOTE: we make the (potentially untrue) assumption here that
// if the owner is enhanced, then all classes are enhanced.

if ( value instanceof ToOne toOne ) {

Expand All @@ -64,17 +62,17 @@ public static boolean includeInBaseFetchGroup(

// it is lazy. see if we should select the FK

if ( bootMapping.getLazyGroup() != null ) {
if ( property.getLazyGroup() != null ) {
// a non-base fetch group was explicitly specified
//
// really this should indicate to not select it as part of the base group.
// however, at the time being that leads to inefficient SQL - so for now
// we simply log a message that we are ignoring the `@LazyGroup` for to-ones

BYTECODE_INTERCEPTOR_LOGGER.lazyGroupIgnoredForToOne(
bootMapping.getLazyGroup(),
bootMapping.getPersistentClass().getEntityName(),
bootMapping.getName()
property.getLazyGroup(),
property.getPersistentClass().getEntityName(),
property.getName()
);

// at a later time - for example 6.0 when we can implement the join solution
Expand All @@ -84,29 +82,30 @@ public static boolean includeInBaseFetchGroup(
// for now, fall through
}

if ( ! toOne.isReferenceToPrimaryKey() ) {
if ( !toOne.isReferenceToPrimaryKey() ) {
// we do not have a reference to the associated primary-key
return false;
}

if ( toOne.getColumnSpan() == 0 ) {
// generally this would indicate a "shared PK" on-to-one and there
// generally this would indicate a "shared PK" one-to-one and there
// is no column for the association on the owner table - do not add
// the association to the base group (which would force an immediate
// select from the association table effectively making this
// association non-lazy)
return false;
}

final boolean unwrapExplicitlyRequested = toOne.isUnwrapProxy() && !toOne.isUnwrapProxyImplicit();
final boolean unwrapExplicitlyRequested =
toOne.isUnwrapProxy() && !toOne.isUnwrapProxyImplicit();

if ( inheritanceChecker.hasSubclasses( toOne.getReferencedEntityName() ) ) {
// the associated type has subclasses - we cannot use the enhanced proxy and will generate a HibernateProxy
if ( unwrapExplicitlyRequested ) {
// NO_PROXY was explicitly requested
BYTECODE_INTERCEPTOR_LOGGER.lazyNoProxyButAssociatedHasSubclasses(
bootMapping.getPersistentClass().getEntityName(),
bootMapping.getName(),
property.getPersistentClass().getEntityName(),
property.getName(),
toOne.getReferencedEntityName()
);
}
Expand All @@ -117,8 +116,8 @@ public static boolean includeInBaseFetchGroup(
if ( toOne instanceof ManyToOne manyToOne && manyToOne.isIgnoreNotFound() ) {
if ( unwrapExplicitlyRequested ) {
BYTECODE_INTERCEPTOR_LOGGER.notFoundIgnoreWithNoProxySkippingFkSelection(
bootMapping.getPersistentClass().getEntityName(),
bootMapping.getName()
property.getPersistentClass().getEntityName(),
property.getName()
);
return false;
}
Expand All @@ -135,15 +134,15 @@ public static boolean includeInBaseFetchGroup(
}

return collectionsInDefaultFetchGroupEnabled && ( value instanceof Collection )
|| ! bootMapping.isLazy();
|| ! property.isLazy();
}

public static <T> T performWork(
BytecodeLazyAttributeInterceptor interceptor,
BiFunction<SharedSessionContractImplementor, Boolean, T> work,
String entityName,
String attributeName) {
SharedSessionContractImplementor session = interceptor.getLinkedSession();
var session = interceptor.getLinkedSession();

final boolean isTempSession;
final boolean isJta;
Expand Down Expand Up @@ -236,23 +235,20 @@ enum Cause {
NO_SF_UUID
}

private static LazyInitializationException createLazyInitializationException(final Cause cause, final String entityName, final String attributeName) {
final String reason = switch ( cause ) {
case NO_SESSION -> "no session and settings disallow loading outside the Session";
case CLOSED_SESSION -> "session is closed and settings disallow loading outside the Session";
case DISCONNECTED_SESSION -> "session is disconnected and settings disallow loading outside the Session";
case NO_SF_UUID -> "could not determine SessionFactory UUId to create temporary Session for loading";
};

final String message = String.format(
private static LazyInitializationException createLazyInitializationException(
Cause cause, String entityName, String attributeName) {
return new LazyInitializationException( String.format(
Locale.ROOT,
"Unable to perform requested lazy initialization [%s.%s] - %s",
entityName,
attributeName,
reason
);

return new LazyInitializationException( message );
switch ( cause ) {
case NO_SESSION -> "no session and settings disallow loading outside the Session";
case CLOSED_SESSION -> "session is closed and settings disallow loading outside the Session";
case DISCONNECTED_SESSION -> "session is disconnected and settings disallow loading outside the Session";
case NO_SF_UUID -> "could not determine SessionFactory UUId to create temporary Session for loading";
}
) );
}

private static SharedSessionContractImplementor openTemporarySessionForLoading(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,14 @@
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributesMetadata;
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
import org.hibernate.bytecode.spi.NotInstrumentedException;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.EntityHolder;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.ManagedEntity;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.engine.spi.SelfDirtinessTracker;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.engine.spi.Status;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.CompositeType;

import org.checkerframework.checker.nullness.qual.Nullable;
Expand All @@ -50,9 +46,9 @@ public static BytecodeEnhancementMetadataPojoImpl from(
CompositeType nonAggregatedCidMapper,
boolean collectionsInDefaultFetchGroupEnabled,
Metadata metadata) {
final Class<?> mappedClass = persistentClass.getMappedClass();
final var mappedClass = persistentClass.getMappedClass();
final boolean enhancedForLazyLoading = isPersistentAttributeInterceptableType( mappedClass );
final LazyAttributesMetadata lazyAttributesMetadata = enhancedForLazyLoading
final var lazyAttributesMetadata = enhancedForLazyLoading
? LazyAttributesMetadata.from( persistentClass, true, collectionsInDefaultFetchGroupEnabled, metadata )
: LazyAttributesMetadata.nonEnhanced( persistentClass.getEntityName() );

Expand Down Expand Up @@ -139,7 +135,7 @@ public boolean isAttributeLoaded(Object entity, String attributeName) {
return true;
}

final BytecodeLazyAttributeInterceptor interceptor = extractLazyInterceptor( entity );
final var interceptor = extractLazyInterceptor( entity );
if ( interceptor instanceof LazyAttributeLoadingInterceptor ) {
return interceptor.isAttributeLoaded( attributeName );
}
Expand All @@ -154,12 +150,12 @@ public boolean isAttributeLoaded(Object entity, String attributeName) {

@Override
public PersistentAttributeInterceptable createEnhancedProxy(EntityKey entityKey, boolean addEmptyEntry, SharedSessionContractImplementor session) {
final EntityPersister persister = entityKey.getPersister();
final var persister = entityKey.getPersister();
final Object identifier = entityKey.getIdentifier();
final PersistenceContext persistenceContext = session.getPersistenceContext();
final var persistenceContext = session.getPersistenceContext();

// first, instantiate the entity instance to use as the proxy
final PersistentAttributeInterceptable entity = asPersistentAttributeInterceptable( persister.instantiate( identifier, session ) );
final var entity = asPersistentAttributeInterceptable( persister.instantiate( identifier, session ) );

// clear the fields that are marked as dirty in the dirtiness tracker
processIfSelfDirtinessTracker( entity, BytecodeEnhancementMetadataPojoImpl::clearDirtyAttributes );
Expand All @@ -170,8 +166,8 @@ public PersistentAttributeInterceptable createEnhancedProxy(EntityKey entityKey,

// if requested, add the "holder entry" to the PC
if ( addEmptyEntry ) {
EntityHolder entityHolder = persistenceContext.getEntityHolder( entityKey );
EntityEntry entityEntry = persistenceContext.addEntry(
final var entityHolder = persistenceContext.getEntityHolder( entityKey );
final var entityEntry = persistenceContext.addEntry(
entity,
Status.MANAGED,
// loaded state
Expand Down Expand Up @@ -223,14 +219,12 @@ public LazyAttributeLoadingInterceptor injectInterceptor(
)
);
}
final LazyAttributeLoadingInterceptor interceptor = new LazyAttributeLoadingInterceptor(
this.lazyAttributeLoadingInterceptorState,
final var interceptor = new LazyAttributeLoadingInterceptor(
lazyAttributeLoadingInterceptorState,
identifier,
session
);

injectInterceptor( entity, interceptor, session );

return interceptor;
}

Expand All @@ -257,10 +251,11 @@ public void injectEnhancedEntityAsProxyInterceptor(
//This state object needs to be lazily initialized as it needs access to the Persister, but once
//initialized it can be reused across multiple sessions.
public EnhancementAsProxyLazinessInterceptor.EntityRelatedState getEnhancementAsProxyLazinessInterceptorMetastate(SharedSessionContractImplementor session) {
EnhancementAsProxyLazinessInterceptor.EntityRelatedState state = this.enhancementAsProxyInterceptorState;
var state = this.enhancementAsProxyInterceptorState;
if ( state == null ) {
final EntityPersister entityPersister = session.getFactory().getMappingMetamodel()
.getEntityDescriptor( entityName );
final var entityPersister =
session.getFactory().getMappingMetamodel()
.getEntityDescriptor( entityName );
state = new EnhancementAsProxyLazinessInterceptor.EntityRelatedState(
entityPersister,
nonAggregatedCidMapper,
Expand Down
Loading