matrei opened a new issue, #16659:
URL: https://github.com/apache/grails-core/issues/16659

   ### Summary
   
   With GORM for Hibernate 7, Hibernate logs a warning at startup for every 
lazy many-to-one association that has no fetch mapping:
   
   ```
   WARN org.hibernate.orm.core : HHH000510: Association with '@Fetch(JOIN)' and 
'fetch=FetchType.LAZY' found. This is interpreted as lazy: 
NavigableRole[pingcrm.Contact].account
   WARN org.hibernate.orm.core : HHH000510: Association with '@Fetch(JOIN)' and 
'fetch=FetchType.LAZY' found. This is interpreted as lazy: 
NavigableRole[pingcrm.Contact].organization
   WARN org.hibernate.orm.core : HHH000510: Association with '@Fetch(JOIN)' and 
'fetch=FetchType.LAZY' found. This is interpreted as lazy: 
NavigableRole[pingcrm.Organization].account
   WARN org.hibernate.orm.core : HHH000510: Association with '@Fetch(JOIN)' and 
'fetch=FetchType.LAZY' found. This is interpreted as lazy: 
NavigableRole[pingcrm.auth.UserRole#{id}].role
   WARN org.hibernate.orm.core : HHH000510: Association with '@Fetch(JOIN)' and 
'fetch=FetchType.LAZY' found. This is interpreted as lazy: 
NavigableRole[pingcrm.auth.UserRole#{id}].user
   ```
   
   The associations are plain properties such as `Account account`, which GORM 
maps as lazy by default. Hibernate still loads them lazily, so the behaviour is 
correct, but every application gets one warning per association, for mappings 
the application did not write.
   
   Seen with Grails 8.0.0, `grails-data-hibernate7` 8.0.0 and Hibernate 
7.4.10.Final.
   
   ### Cause
   
   `ManyToOneValuesBinder.bindManyToOneValues` sets the fetch mode and laziness 
of a many-to-one separately:
   
   ```java
   var fetchMode = 
Optional.ofNullable(config.getFetchMode()).orElse(FetchMode.DEFAULT);
   manyToOne.setFetchMode(fetchMode);
   manyToOne.setLazy(property.isLazy());
   ```
   
   Without a fetch mapping, the association gets `FetchMode.DEFAULT` and `lazy 
= true`.
   
   In Hibernate 7.4, `FetchOptionsHelper.determineFetchStyleByMetadata` turns 
`FetchMode.DEFAULT` for a to-one into `FetchStyle.JOIN` when the associated 
entity is not batch loadable and has no proxy (`!persister.hasProxy()`). 
`determineFetchTiming` then finds a JOIN style on a lazy association, logs 
HHH000510 and returns `FetchTiming.DELAYED`:
   
   ```java
   case JOIN: {
       if ( lazy ) {
           CORE_LOGGER.fetchModeJoinWithLazyWarning( role );
           return FetchTiming.DELAYED;
       }
       return FetchTiming.IMMEDIATE;
   }
   ```
   
   Associations mapped as eager, such as one with 
`fetchStrategy(FetchType.EAGER)`, are not lazy and do not log the warning.
   
   ### Workaround
   
   Mapping the fetch mode of the association as `SELECT` avoids the warning:
   
   ```groovy
   import org.hibernate.FetchMode
   
   static final MappingDefinition<Mapping, PropertyConfig> mapping = 
MappingBuilder.orm {
       property('organization') {
           fetch = FetchMode.SELECT
       }
   }
   ```
   
   With this mapping, the warning for `Contact.organization` is no longer 
logged, while the ones for the other associations still are. This has to be 
done for every lazy many-to-one association, though, including those of plugin 
domain classes.
   
   ### Suggested fix
   
   When no fetch mode is mapped, `ManyToOneValuesBinder` could use 
`FetchMode.SELECT` for a lazy association, the fetch mode that matches lazy 
loading, and keep `FetchMode.DEFAULT` for an eager one. Lazy loading with a 
`SELECT` fetch mode is the combination Hibernate expects, so it would not warn, 
as the workaround shows.
   
   I have not tried the change in GORM itself, only the equivalent mapping in 
an application.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to