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 @@ -9,6 +9,7 @@
import java.io.IOException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.util.Map;
import java.util.Properties;
import java.util.ServiceConfigurationError;
import java.util.Set;
Expand Down Expand Up @@ -73,8 +74,20 @@ public interface CoreMessageLogger extends BasicLogger {
void callingJoinTransactionOnNonJtaEntityManager();

@LogMessage(level = DEBUG)
@Message(value = "Closing", id = 31)
void closing();
@Message(value = "Instantiating factory with settings: %s", id = 30)
void instantiatingFactory(Map<String, Object> settings);

@LogMessage(level = DEBUG)
@Message(value = "Closing factory", id = 31)
void closingFactory();

@LogMessage(level = DEBUG)
@Message(value = "Serializing factory: %s", id = 32)
void serializingFactory(String uuid);

@LogMessage(level = DEBUG)
@Message(value = "Deserialized factory: %s", id = 33)
void deserializedFactory(String uuid);

@LogMessage(level = WARN)
@Message(value = "Composite-id class does not override equals(): %s", id = 38)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import javax.naming.Reference;
import javax.naming.StringRefAddr;

import org.hibernate.AssertionFailure;
import org.hibernate.CustomEntityDirtinessStrategy;
import org.hibernate.EntityNameResolver;
import org.hibernate.FlushMode;
Expand Down Expand Up @@ -90,17 +89,11 @@
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.metamodel.spi.RuntimeMetamodelsImplementor;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.procedure.spi.ProcedureCallImplementor;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.proxy.LazyInitializer;
import org.hibernate.query.BindingContext;
import org.hibernate.query.hql.spi.SqmQueryImplementor;
import org.hibernate.query.internal.QueryEngineImpl;
import org.hibernate.query.named.NamedObjectRepository;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.sql.internal.SqlTranslationEngineImpl;
import org.hibernate.query.sql.spi.NativeQueryImplementor;
import org.hibernate.query.sql.spi.SqlTranslationEngine;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
Expand Down Expand Up @@ -167,7 +160,7 @@
* @author Steve Ebersole
* @author Chris Cranford
*/
public class SessionFactoryImpl implements SessionFactoryImplementor, BindingContext {
public class SessionFactoryImpl implements SessionFactoryImplementor {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( SessionFactoryImpl.class );

private final String name;
Expand All @@ -182,12 +175,10 @@ public class SessionFactoryImpl implements SessionFactoryImplementor, BindingCon
private final transient Map<String,Object> settings;

private final transient SessionFactoryServiceRegistry serviceRegistry;
private final transient EventEngine eventEngine;//Needs to be closed!
private final transient EventEngine eventEngine;
private final transient JdbcServices jdbcServices;
private final transient SqlStringGenerationContext sqlStringGenerationContext;

// todo : org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor too?

private final transient RuntimeMetamodelsImplementor runtimeMetamodels;
private final PersistenceUnitUtil jpaPersistenceUnitUtil;
private final transient CacheImplementor cacheAccess;
Expand Down Expand Up @@ -245,7 +236,7 @@ public SessionFactoryImpl(
settings = getSettings( options, serviceRegistry );
maskOutSensitiveInformation( settings );
deprecationCheck( settings );
LOG.debugf( "Instantiating SessionFactory with settings: %s", settings );
LOG.instantiatingFactory( settings );

sqlStringGenerationContext = createSqlStringGenerationContext( bootMetamodel, options, jdbcServices );

Expand All @@ -258,7 +249,6 @@ public SessionFactoryImpl(
}

filters = new HashMap<>( bootMetamodel.getFilterDefinitions() );
LOG.debugf( "Session factory constructed with filter configurations : %s", filters );

final FilterDefinition tenantFilter = filters.get( TenantIdBinder.FILTER_NAME );
if ( tenantFilter == null ) {
Expand Down Expand Up @@ -293,21 +283,26 @@ public SessionFactoryImpl(

primeSecondLevelCacheRegions( bootMetamodel );

// we build this before creating the runtime metamodel
// create the empty runtime metamodels object
final RuntimeMetamodelsImpl runtimeMetamodelsImpl = new RuntimeMetamodelsImpl( typeConfiguration );
runtimeMetamodels = runtimeMetamodelsImpl;

// we build this before creating the runtime metamodels
// because the persisters need the SqmFunctionRegistry
// to translate SQL formulas ... but, if we fix Dialect
// to translate SQL formulas. But, if we fix Dialect
// as I proposed, so that it can contribute functions
// to the SqmFunctionRegistry before the QueryEngine is
// created, then we can split creation of QueryEngine
// and SqmFunctionRegistry, instantiating just the
// registry here, and doing the engine later
queryEngine = new QueryEngineImpl( bootMetamodel, options, this, serviceRegistry, settings, name );
// registry here, and doing the engine later, and we
// can thus untie this nasty little knot. Alternatively,
// perhaps it's not really appropriate that they use the
// SqmFunctionRegistry for that purpose at all?
queryEngine = new QueryEngineImpl( bootMetamodel, options, runtimeMetamodels, serviceRegistry, settings, name );
final Map<String, FetchProfile> fetchProfiles = new HashMap<>();
sqlTranslationEngine = new SqlTranslationEngineImpl( this, typeConfiguration, fetchProfiles );

// create runtime metamodels (mapping and JPA)
final RuntimeMetamodelsImpl runtimeMetamodelsImpl = new RuntimeMetamodelsImpl();
runtimeMetamodels = runtimeMetamodelsImpl;
// now actually create the mapping and JPA metamodels
final MappingMetamodelImpl mappingMetamodelImpl = new MappingMetamodelImpl( typeConfiguration, serviceRegistry );
runtimeMetamodelsImpl.setMappingMetamodel( mappingMetamodelImpl );
mappingMetamodelImpl.finishInitialization(
Expand Down Expand Up @@ -359,12 +354,12 @@ public SessionFactoryImpl(
close();
}
catch (Exception closeException) {
LOG.debug( "Eating error closing the SessionFactory after a failed attempt to start it" );
LOG.trace( "Eating error closing factory after failed instantiation" );
}
throw e;
}

LOG.debug( "Instantiated SessionFactory" );
LOG.debug( "Instantiated factory" );
}

private EventMonitor loadEventMonitor() {
Expand Down Expand Up @@ -481,10 +476,12 @@ private SessionBuilderImpl buildTemporarySessionOpenOptions() {
private void primeSecondLevelCacheRegions(MetadataImplementor mappingMetadata) {
final Map<String, DomainDataRegionConfigImpl.Builder> regionConfigBuilders = new ConcurrentHashMap<>();

// todo : ultimately this code can be made more efficient when we have a better intrinsic understanding of the hierarchy as a whole
// TODO: ultimately this code can be made more efficient when we have
// a better intrinsic understanding of the hierarchy as a whole

for ( PersistentClass bootEntityDescriptor : mappingMetadata.getEntityBindings() ) {
final AccessType accessType = AccessType.fromExternalName( bootEntityDescriptor.getCacheConcurrencyStrategy() );
final AccessType accessType =
AccessType.fromExternalName( bootEntityDescriptor.getCacheConcurrencyStrategy() );

if ( accessType != null ) {
if ( bootEntityDescriptor.isCached() ) {
Expand Down Expand Up @@ -533,29 +530,25 @@ private void primeSecondLevelCacheRegions(MetadataImplementor mappingMetadata) {
}

@Override
public SessionImplementor openSession() throws HibernateException {
//The defaultSessionOpenOptions can't be used in some cases; for example when using a TenantIdentifierResolver.
if ( defaultSessionOpenOptions != null ) {
return defaultSessionOpenOptions.openSession();
}
else {
return withOptions().openSession();
}
public SessionImplementor openSession() {
// The defaultSessionOpenOptions can't be used in some cases;
// for example when using a TenantIdentifierResolver.
return defaultSessionOpenOptions != null
? defaultSessionOpenOptions.openSession()
: withOptions().openSession();
}

@Override
public SessionImpl openTemporarySession() throws HibernateException {
//The temporarySessionOpenOptions can't be used in some cases; for example when using a TenantIdentifierResolver.
if ( temporarySessionOpenOptions != null ) {
return temporarySessionOpenOptions.openSession();
}
else {
return buildTemporarySessionOpenOptions().openSession();
}
public SessionImpl openTemporarySession() {
// The temporarySessionOpenOptions can't be used in some cases;
// for example when using a TenantIdentifierResolver.
return temporarySessionOpenOptions != null
? temporarySessionOpenOptions.openSession()
: buildTemporarySessionOpenOptions().openSession();
}

@Override
public Session getCurrentSession() throws HibernateException {
public Session getCurrentSession() {
if ( currentSessionContext == null ) {
throw new HibernateException( "No CurrentSessionContext configured" );
}
Expand Down Expand Up @@ -770,7 +763,7 @@ public Interceptor getInterceptor() {
@Override
public Reference getReference() {
// from javax.naming.Referenceable
LOG.debug( "Returning a Reference to the SessionFactory" );
LOG.debug( "Returning a Reference to the factory" );
return new Reference(
SessionFactoryImpl.class.getName(),
new StringRefAddr( "uuid", getUuid() ),
Expand All @@ -794,7 +787,7 @@ public Reference getReference() {
* collector release the memory.
*/
@Override
public void close() throws HibernateException {
public void close() {
synchronized (this) {
if ( status != Status.OPEN ) {
if ( getSessionFactoryOptions().getJpaCompliance().isJpaClosedComplianceEnabled() ) {
Expand All @@ -809,7 +802,7 @@ public void close() throws HibernateException {
}

try {
LOG.closing();
LOG.closingFactory();
observer.sessionFactoryClosing( this );

// NOTE : the null checks below handle cases where close is called from
Expand Down Expand Up @@ -874,58 +867,7 @@ public PersistenceUnitTransactionType getTransactionType() {
@Override
public void addNamedQuery(String name, Query query) {
validateNotClosed();

// NOTE : we use Query#unwrap here (rather than direct type checking)
// to account for possibly wrapped query implementations

// first, handle StoredProcedureQuery
final NamedObjectRepository namedObjectRepository = getQueryEngine().getNamedObjectRepository();
try {
final ProcedureCallImplementor<?> unwrapped = query.unwrap( ProcedureCallImplementor.class );
if ( unwrapped != null ) {
namedObjectRepository.registerCallableQueryMemento( name, unwrapped.toMemento( name ) );
return;
}
}
catch ( PersistenceException ignore ) {
// this means 'query' is not a ProcedureCallImplementor
}

// then try as a native-SQL or JPQL query
try {
final QueryImplementor<?> queryImplementor = query.unwrap( QueryImplementor.class );
if ( queryImplementor != null ) {
// create and register the proper NamedQueryDefinition...
if ( queryImplementor instanceof NativeQueryImplementor<?> nativeQueryImplementor ) {
namedObjectRepository.registerNativeQueryMemento(
name,
nativeQueryImplementor.toMemento( name )
);

}
else if ( queryImplementor instanceof SqmQueryImplementor<?> sqmQueryImplementor ) {
namedObjectRepository.registerSqmQueryMemento(
name,
sqmQueryImplementor.toMemento( name )
);
}
else {
throw new AssertionFailure("unknown QueryImplementor");
}
return;
}
}
catch ( PersistenceException ignore ) {
// this means 'query' is not a native-SQL or JPQL query
}

// if we get here, we are unsure how to properly unwrap the incoming query to extract the needed information
throw new PersistenceException(
String.format(
"Unsure how to properly unwrap given Query [%s] as basis for named query",
query
)
);
getQueryEngine().getNamedObjectRepository().registerNamedQuery( name, query );
}

@Override
Expand Down Expand Up @@ -1004,7 +946,7 @@ public StatisticsImplementor getStatistics() {
return statistics;
}

public FilterDefinition getFilterDefinition(String filterName) throws HibernateException {
public FilterDefinition getFilterDefinition(String filterName) {
final FilterDefinition filterDefinition = filters.get( filterName );
if ( filterDefinition == null ) {
throw new UnknownFilterException( filterName );
Expand Down Expand Up @@ -1543,11 +1485,9 @@ public JavaType<Object> getTenantIdentifierJavaType() {
*/
@Serial
private void writeObject(ObjectOutputStream out) throws IOException {
if ( LOG.isDebugEnabled() ) {
LOG.debugf( "Serializing: %s", getUuid() );
}
LOG.serializingFactory( getUuid() );
out.defaultWriteObject();
LOG.trace( "Serialized" );
LOG.trace( "Serialized factory" );
}

/**
Expand All @@ -1560,11 +1500,9 @@ private void writeObject(ObjectOutputStream out) throws IOException {
*/
@Serial
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
LOG.trace( "Deserializing" );
LOG.trace( "Deserializing factory" );
in.defaultReadObject();
if ( LOG.isDebugEnabled() ) {
LOG.debugf( "Deserialized: %s", getUuid() );
}
LOG.deserializedFactory( getUuid() );
}

/**
Expand All @@ -1580,15 +1518,15 @@ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundE
*/
@Serial
private Object readResolve() throws InvalidObjectException {
LOG.trace( "Resolving serialized SessionFactory" );
LOG.trace( "Resolving serialized factory" );
return locateSessionFactoryOnDeserialization( getUuid(), name );
}

private static SessionFactory locateSessionFactoryOnDeserialization(String uuid, String name)
throws InvalidObjectException{
final SessionFactory uuidResult = SessionFactoryRegistry.INSTANCE.getSessionFactory( uuid );
if ( uuidResult != null ) {
LOG.debugf( "Resolved SessionFactory by UUID [%s]", uuid );
LOG.debug( "Resolved factory by UUID: " + uuid );
return uuidResult;
}

Expand All @@ -1597,12 +1535,12 @@ private static SessionFactory locateSessionFactoryOnDeserialization(String uuid,
if ( name != null ) {
final SessionFactory namedResult = SessionFactoryRegistry.INSTANCE.getNamedSessionFactory( name );
if ( namedResult != null ) {
LOG.debugf( "Resolved SessionFactory by name [%s]", name );
LOG.debug( "Resolved factory by name: " + name );
return namedResult;
}
}

throw new InvalidObjectException( "Could not find a SessionFactory [uuid=" + uuid + ",name=" + name + "]" );
throw new InvalidObjectException( "No SessionFactory with uuid [" + uuid + "] and name [" + name + "]" );
}

/**
Expand All @@ -1627,7 +1565,7 @@ void serialize(ObjectOutputStream oos) throws IOException {
* @throws IOException indicates problems reading back serial data stream
*/
static SessionFactoryImpl deserialize(ObjectInputStream ois) throws IOException {
LOG.trace( "Deserializing SessionFactory from Session" );
LOG.trace( "Resolving factory from deserialized session" );
final String uuid = ois.readUTF();
boolean isNamed = ois.readBoolean();
final String name = isNamed ? ois.readUTF() : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,24 @@
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.metamodel.spi.RuntimeMetamodelsImplementor;
import org.hibernate.type.Type;
import org.hibernate.type.spi.TypeConfiguration;

/**
* @author Steve Ebersole
*/
public class RuntimeMetamodelsImpl implements RuntimeMetamodelsImplementor {

private final TypeConfiguration typeConfiguration;
private JpaMetamodelImplementor jpaMetamodel;
private MappingMetamodelImplementor mappingMetamodel;

public RuntimeMetamodelsImpl() {
public RuntimeMetamodelsImpl(TypeConfiguration typeConfiguration) {
this.typeConfiguration = typeConfiguration;
}

@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}

@Override
Expand Down
Loading
Loading