HHH-11935 : Log a warning and update documentation that enabling "empty" composites is an experimental feature

This commit is contained in:
Gail Badner 2017-08-17 21:44:17 -07:00
parent 12616d44e2
commit 407360d957
4 changed files with 40 additions and 1 deletions

View File

@ -290,6 +290,9 @@ Such a need is very uncommon and not recommended.
3+|Misc options 3+|Misc options
|`hibernate.create_empty_composites.enabled` |`true` or `false` (default value) | Enable instantiation of composite/embeddable objects when all of its attribute values are `null`. The default (and historical) behavior is that a `null` reference will be used to represent the composite when all of its attributes are `null`. |`hibernate.create_empty_composites.enabled` |`true` or `false` (default value) | Enable instantiation of composite/embeddable objects when all of its attribute values are `null`. The default (and historical) behavior is that a `null` reference will be used to represent the composite when all of its attributes are `null`.
This is an experimental feature that has known issues. It should not be used in production until it is stabilized. See Hibernate Jira issue https://hibernate.atlassian.net/browse/HHH-11936[HHH-11936] for details.
|`hibernate.entity_dirtiness_strategy` | fully-qualified class name or an actual `CustomEntityDirtinessStrategy` instance | Setting to identify a `org.hibernate.CustomEntityDirtinessStrategy` to use. |`hibernate.entity_dirtiness_strategy` | fully-qualified class name or an actual `CustomEntityDirtinessStrategy` instance | Setting to identify a `org.hibernate.CustomEntityDirtinessStrategy` to use.
|`hibernate.default_entity_mode` |`pojo` (default value) or `dynamic-map` |Default `EntityMode` for entity representation for all sessions opened from this `SessionFactory`, defaults to `pojo`. |`hibernate.default_entity_mode` |`pojo` (default value) or `dynamic-map` |Default `EntityMode` for entity representation for all sessions opened from this `SessionFactory`, defaults to `pojo`.
|=================================================================================================================================================================================================================================== |===================================================================================================================================================================================================================================

View File

@ -1571,9 +1571,12 @@ public interface AvailableSettings {
String PROCEDURE_NULL_PARAM_PASSING = "hibernate.proc.param_null_passing"; String PROCEDURE_NULL_PARAM_PASSING = "hibernate.proc.param_null_passing";
/** /**
* Enable instantiation of composite/embedded objects when all of its attribute values are {@code null}. * [EXPERIMENTAL] Enable instantiation of composite/embedded objects when all of its attribute values are {@code null}.
* The default (and historical) behavior is that a {@code null} reference will be used to represent the * The default (and historical) behavior is that a {@code null} reference will be used to represent the
* composite when all of its attributes are {@code null} * composite when all of its attributes are {@code null}
* <p/>
* This is an experimental feature that has known issues. It should not be used in production
* until it is stabilized. See Hibernate Jira issue HHH-11936 for details.
* *
* @since 5.1 * @since 5.1
*/ */

View File

@ -24,6 +24,7 @@ import javax.transaction.SystemException;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.cache.CacheException; import org.hibernate.cache.CacheException;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver; import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
import org.hibernate.engine.jndi.JndiException; import org.hibernate.engine.jndi.JndiException;
@ -1773,4 +1774,16 @@ public interface CoreMessageLogger extends BasicLogger {
@LogMessage(level = WARN) @LogMessage(level = WARN)
@Message(value = "@javax.persistence.Cacheable or @org.hibernate.annotations.Cache used on a non-root entity: ignored for %s", id = 482) @Message(value = "@javax.persistence.Cacheable or @org.hibernate.annotations.Cache used on a non-root entity: ignored for %s", id = 482)
void cacheOrCacheableAnnotationOnNonRoot(String className); void cacheOrCacheableAnnotationOnNonRoot(String className);
@LogMessage(level = WARN)
@Message(
id = 483,
value = "An experimental feature has been enabled (" +
AvailableSettings.CREATE_EMPTY_COMPOSITES_ENABLED +
"=true) that instantiates empty composite/embedded " +
"objects when all of its attribute values are null. This feature has known issues and " +
"should not be used in production until it is stabilized. See Hibernate Jira " +
"issue HHH-11936 for details."
)
void emptyCompositesEnabled();
} }

View File

@ -93,6 +93,7 @@ import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.integrator.spi.Integrator; import org.hibernate.integrator.spi.Integrator;
import org.hibernate.integrator.spi.IntegratorService; import org.hibernate.integrator.spi.IntegratorService;
import org.hibernate.internal.util.config.ConfigurationException; import org.hibernate.internal.util.config.ConfigurationException;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.jpa.internal.AfterCompletionActionLegacyJpaImpl; import org.hibernate.jpa.internal.AfterCompletionActionLegacyJpaImpl;
import org.hibernate.jpa.internal.ExceptionMapperLegacyJpaImpl; import org.hibernate.jpa.internal.ExceptionMapperLegacyJpaImpl;
import org.hibernate.jpa.internal.ManagedFlushCheckerLegacyJpaImpl; import org.hibernate.jpa.internal.ManagedFlushCheckerLegacyJpaImpl;
@ -235,7 +236,10 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
); );
} }
} }
maskOutSensitiveInformation(this.properties); maskOutSensitiveInformation(this.properties);
logIfEmptyCompositesEnabled( this.properties );
this.sqlFunctionRegistry = new SQLFunctionRegistry( jdbcServices.getJdbcEnvironment().getDialect(), options.getCustomSqlFunctionMap() ); this.sqlFunctionRegistry = new SQLFunctionRegistry( jdbcServices.getJdbcEnvironment().getDialect(), options.getCustomSqlFunctionMap() );
this.cacheAccess = this.serviceRegistry.getService( CacheImplementor.class ); this.cacheAccess = this.serviceRegistry.getService( CacheImplementor.class );
this.criteriaBuilder = new CriteriaBuilderImpl( this ); this.criteriaBuilder = new CriteriaBuilderImpl( this );
@ -1567,4 +1571,20 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
props.put( setting, "****" ); props.put( setting, "****" );
} }
} }
private void logIfEmptyCompositesEnabled(Map<String, Object> props ) {
final boolean isEmptyCompositesEnabled = ConfigurationHelper.getBoolean(
AvailableSettings.CREATE_EMPTY_COMPOSITES_ENABLED,
props,
false
);
if ( isEmptyCompositesEnabled ) {
// It would be nice to do this logging in ComponentMetamodel, where
// AvailableSettings.CREATE_EMPTY_COMPOSITES_ENABLED is actually used.
// Unfortunately that would end up logging a message several times for
// each embeddable/composite. Doing it here will log the message only
// once.
LOG.emptyCompositesEnabled();
}
}
} }