Log warning when FetchStyle.JOIN is used with LAZY and add migration guide entry for fetch all properties

This commit is contained in:
Christian Beikov 2022-02-15 09:47:12 +01:00
parent dc6ad33cfc
commit b85f530b42
4 changed files with 35 additions and 5 deletions

View File

@ -1788,4 +1788,8 @@ public interface CoreMessageLogger extends BasicLogger {
@Message(value = "Multi-table insert is not available due to missing identity and window function support for: %s", id = 509)
void multiTableInsertNotAvailable(String entityName);
@LogMessage(level = WARN)
@Message(value = "Association with `fetch=\"join\"`/`@Fetch(FetchMode.JOIN)` and `lazy=\"true\"`/`FetchType.LAZY` found. This will be interpreted as lazy: %s", id = 510)
void fetchModeJoinWithLazyWarning(String role);
}

View File

@ -10,6 +10,8 @@ import org.hibernate.FetchMode;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.persister.collection.AbstractCollectionPersister;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
@ -20,6 +22,9 @@ import org.hibernate.type.AssociationType;
* @author Steve Ebersole
*/
public final class FetchOptionsHelper {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( FetchOptionsHelper.class );
private FetchOptionsHelper() {
}
@ -90,10 +95,15 @@ public final class FetchOptionsHelper {
FetchStyle style,
AssociationType type,
boolean lazy,
String role,
SessionFactoryImplementor sessionFactory) {
switch ( style ) {
case JOIN: {
return lazy ? FetchTiming.DELAYED : FetchTiming.IMMEDIATE;
if ( lazy ) {
LOG.fetchModeJoinWithLazyWarning( role );
return FetchTiming.DELAYED;
}
return FetchTiming.IMMEDIATE;
}
case BATCH:
case SUBSELECT:

View File

@ -754,6 +754,7 @@ public class MappingModelCreationHelper {
style,
collectionDescriptor.getCollectionType(),
collectionDescriptor.isLazy(),
collectionDescriptor.getRole(),
sessionFactory
);
@ -1579,17 +1580,17 @@ public class MappingModelCreationHelper {
);
final FetchTiming fetchTiming;
final String role = declaringType.getNavigableRole().toString() + "." + bootProperty.getName();
final boolean lazy = value.isLazy();
if ( lazy && entityPersister.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() ) {
if ( value.isUnwrapProxy() ) {
fetchTiming = FetchOptionsHelper.determineFetchTiming( fetchStyle, type, lazy, sessionFactory );
fetchTiming = FetchOptionsHelper.determineFetchTiming( fetchStyle, type, lazy, role, sessionFactory );
}
else if ( value instanceof ManyToOne && value.isNullable() && ( (ManyToOne) value ).isIgnoreNotFound() ) {
fetchTiming = FetchTiming.IMMEDIATE;
}
else {
fetchTiming = FetchOptionsHelper.determineFetchTiming( fetchStyle, type, lazy, sessionFactory );
fetchTiming = FetchOptionsHelper.determineFetchTiming( fetchStyle, type, lazy, role, sessionFactory );
}
}
else if ( !lazy
@ -1598,7 +1599,7 @@ public class MappingModelCreationHelper {
fetchTiming = FetchTiming.IMMEDIATE;
}
else {
fetchTiming = FetchOptionsHelper.determineFetchTiming( fetchStyle, type, lazy, sessionFactory );
fetchTiming = FetchOptionsHelper.determineFetchTiming( fetchStyle, type, lazy, role, sessionFactory );
}
final ToOneAttributeMapping attributeMapping = new ToOneAttributeMapping(

View File

@ -560,6 +560,21 @@ The legacy Hibernate Criteria API which was deprecated back in Hibernate 5.x and
Usually, all queries using the legacy API can be modeled with the JPA Criteria API.
In some cases it is necessary to use the Hibernate JPA Criteria extensions.
=== HQL fetch all properties clause
The `fetch all properties` clause was removed from the HQL language without a replacement.
A similar behavior can be achieved by constructing an entity graph and applying that as load graph:
```java
EntityGraph<Document> entityGraph = entityManager.createEntityGraph( Document.class );
for ( Attribute<Document, ?> attr : entityManager.getMetamodel().entity( Document.class ).getAttributes() ) {
entityGraph.addAttributeNodes( attr.getName() );
}
List<Document> documents = s.createQuery( "from Document", Document.class )
.setHint( "jakarta.persistence.loadgraph", entityGraph )
.getResultList();
```
=== JMX integration
Hibernate no longer provides built-in support for integrating itself with JMX environments.