📄 sessionfactoryimpl.java
字号:
//$Id: SessionFactoryImpl.java 9235 2006-02-08 18:47:07Z steveebersole $
package org.hibernate.impl;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.transaction.TransactionManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.AssertionFailure;
import org.hibernate.ConnectionReleaseMode;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.MappingException;
import org.hibernate.QueryException;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.hibernate.context.CurrentSessionContext;
import org.hibernate.context.ThreadLocalSessionContext;
import org.hibernate.context.JTASessionContext;
import org.hibernate.cache.Cache;
import org.hibernate.cache.CacheConcurrencyStrategy;
import org.hibernate.cache.CacheFactory;
import org.hibernate.cache.CacheKey;
import org.hibernate.cache.QueryCache;
import org.hibernate.cache.UpdateTimestampsCache;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Settings;
import org.hibernate.cfg.Environment;
import org.hibernate.connection.ConnectionProvider;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.FilterDefinition;
import org.hibernate.engine.Mapping;
import org.hibernate.engine.NamedQueryDefinition;
import org.hibernate.engine.NamedSQLQueryDefinition;
import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.query.QueryPlanCache;
import org.hibernate.engine.query.NativeSQLQuerySpecification;
import org.hibernate.event.EventListeners;
import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.UUIDHexGenerator;
import org.hibernate.jdbc.BatcherFactory;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.persister.PersisterFactory;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.stat.Statistics;
import org.hibernate.stat.StatisticsImpl;
import org.hibernate.stat.StatisticsImplementor;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
import org.hibernate.tool.hbm2ddl.SchemaValidator;
import org.hibernate.transaction.TransactionFactory;
import org.hibernate.type.AssociationType;
import org.hibernate.type.Type;
import org.hibernate.util.CollectionHelper;
import org.hibernate.util.ReflectHelper;
import org.hibernate.util.SerializationHelper;
/**
* Concrete implementation of the <tt>SessionFactory</tt> interface. Has the following
* responsibilites
* <ul>
* <li>caches configuration settings (immutably)
* <li>caches "compiled" mappings ie. <tt>EntityPersister</tt>s and
* <tt>CollectionPersister</tt>s (immutable)
* <li>caches "compiled" queries (memory sensitive cache)
* <li>manages <tt>PreparedStatement</tt>s
* <li> delegates JDBC <tt>Connection</tt> management to the <tt>ConnectionProvider</tt>
* <li>factory for instances of <tt>SessionImpl</tt>
* </ul>
* This class must appear immutable to clients, even if it does all kinds of caching
* and pooling under the covers. It is crucial that the class is not only thread
* safe, but also highly concurrent. Synchronization must be used extremely sparingly.
*
* @see org.hibernate.connection.ConnectionProvider
* @see org.hibernate.classic.Session
* @see org.hibernate.hql.QueryTranslator
* @see org.hibernate.persister.entity.EntityPersister
* @see org.hibernate.persister.collection.CollectionPersister
* @author Gavin King
*/
public final class SessionFactoryImpl implements SessionFactory, SessionFactoryImplementor {
private final String name;
private final String uuid;
private final transient Map entityPersisters;
private final transient Map classMetadata;
private final transient Map collectionPersisters;
private final transient Map collectionMetadata;
private final transient Map collectionRolesByEntityParticipant;
private final transient Map identifierGenerators;
private final transient Map namedQueries;
private final transient Map namedSqlQueries;
private final transient Map sqlResultSetMappings;
private final transient Map filters;
private final transient Map imports;
private final transient Interceptor interceptor;
private final transient Settings settings;
private final transient Properties properties;
private transient SchemaExport schemaExport;
private final transient TransactionManager transactionManager;
private final transient QueryCache queryCache;
private final transient UpdateTimestampsCache updateTimestampsCache;
private final transient Map queryCaches;
private final transient Map allCacheRegions = new HashMap();
private final transient StatisticsImpl statistics = new StatisticsImpl(this);
private final transient EventListeners eventListeners;
private final transient CurrentSessionContext currentSessionContext;
private final QueryPlanCache queryPlanCache = new QueryPlanCache( this );
private transient boolean isClosed = false;
private static final IdentifierGenerator UUID_GENERATOR = new UUIDHexGenerator();
private static final Log log = LogFactory.getLog(SessionFactoryImpl.class);
public SessionFactoryImpl(
Configuration cfg,
Mapping mapping,
Settings settings,
EventListeners listeners)
throws HibernateException {
log.info("building session factory");
this.properties = new Properties();
this.properties.putAll( cfg.getProperties() );
this.interceptor = cfg.getInterceptor();
this.settings = settings;
this.eventListeners = listeners;
this.filters = new HashMap();
this.filters.putAll( cfg.getFilterDefinitions() );
if ( log.isDebugEnabled() ) {
log.debug("Session factory constructed with filter configurations : " + filters);
}
if ( log.isDebugEnabled() ) log.debug(
"instantiating session factory with properties: " + properties
);
// Caches
settings.getCacheProvider().start( properties );
//Generators:
identifierGenerators = new HashMap();
Iterator classes = cfg.getClassMappings();
while ( classes.hasNext() ) {
PersistentClass model = (PersistentClass) classes.next();
if ( !model.isInherited() ) {
IdentifierGenerator generator = model.getIdentifier().createIdentifierGenerator(
settings.getDialect(),
settings.getDefaultCatalogName(),
settings.getDefaultSchemaName(),
(RootClass) model
);
identifierGenerators.put( model.getEntityName(), generator );
}
}
//Persisters:
Map caches = new HashMap();
entityPersisters = new HashMap();
Map classMeta = new HashMap();
classes = cfg.getClassMappings();
while ( classes.hasNext() ) {
PersistentClass model = (PersistentClass) classes.next();
model.prepareTemporaryTables( mapping, settings.getDialect() );
String cacheRegion = model.getRootClass().getCacheRegionName();
CacheConcurrencyStrategy cache = (CacheConcurrencyStrategy) caches.get(cacheRegion);
if (cache==null) {
cache = CacheFactory.createCache(
model.getCacheConcurrencyStrategy(),
cacheRegion,
model.isMutable(),
settings,
properties
);
if (cache!=null) {
caches.put(cacheRegion, cache);
allCacheRegions.put( cache.getRegionName(), cache.getCache() );
}
}
EntityPersister cp = PersisterFactory.createClassPersister(model, cache, this, mapping);
entityPersisters.put( model.getEntityName(), cp );
classMeta.put( model.getEntityName(), cp.getClassMetadata() );
}
classMetadata = Collections.unmodifiableMap(classMeta);
Map tmpEntityToCollectionRoleMap = new HashMap();
collectionPersisters = new HashMap();
Iterator collections = cfg.getCollectionMappings();
while ( collections.hasNext() ) {
Collection model = (Collection) collections.next();
CacheConcurrencyStrategy cache = CacheFactory.createCache(
model.getCacheConcurrencyStrategy(),
model.getCacheRegionName(),
true,
settings,
properties
);
if (cache!=null) allCacheRegions.put( cache.getRegionName(), cache.getCache() );
CollectionPersister persister = PersisterFactory.createCollectionPersister(cfg, model, cache, this);
collectionPersisters.put( model.getRole(), persister.getCollectionMetadata() );
Type indexType = persister.getIndexType();
if ( indexType != null && indexType.isAssociationType() && !indexType.isAnyType() ) {
String entityName = ( ( AssociationType ) indexType ).getAssociatedEntityName( this );
Set roles = ( Set ) tmpEntityToCollectionRoleMap.get( entityName );
if ( roles == null ) {
roles = new HashSet();
tmpEntityToCollectionRoleMap.put( entityName, roles );
}
roles.add( persister.getRole() );
}
Type elementType = persister.getElementType();
if ( elementType.isAssociationType() && !elementType.isAnyType() ) {
String entityName = ( ( AssociationType ) elementType ).getAssociatedEntityName( this );
Set roles = ( Set ) tmpEntityToCollectionRoleMap.get( entityName );
if ( roles == null ) {
roles = new HashSet();
tmpEntityToCollectionRoleMap.put( entityName, roles );
}
roles.add( persister.getRole() );
}
}
collectionMetadata = Collections.unmodifiableMap(collectionPersisters);
Iterator itr = tmpEntityToCollectionRoleMap.entrySet().iterator();
while ( itr.hasNext() ) {
final Map.Entry entry = ( Map.Entry ) itr.next();
entry.setValue( Collections.unmodifiableSet( ( Set ) entry.getValue() ) );
}
collectionRolesByEntityParticipant = Collections.unmodifiableMap( tmpEntityToCollectionRoleMap );
//Named Queries:
namedQueries = new HashMap( cfg.getNamedQueries() );
namedSqlQueries = new HashMap( cfg.getNamedSQLQueries() );
sqlResultSetMappings = new HashMap( cfg.getSqlResultSetMappings() );
imports = new HashMap( cfg.getImports() );
// after *all* persisters and named queries are registered
Iterator iter = entityPersisters.values().iterator();
while ( iter.hasNext() ) {
( (EntityPersister) iter.next() ).postInstantiate();
}
iter = collectionPersisters.values().iterator();
while ( iter.hasNext() ) {
( (CollectionPersister) iter.next() ).postInstantiate();
}
//JNDI + Serialization:
name = settings.getSessionFactoryName();
try {
uuid = (String) UUID_GENERATOR.generate(null, null);
}
catch (Exception e) {
throw new AssertionFailure("Could not generate UUID");
}
SessionFactoryObjectFactory.addInstance(uuid, name, this, properties);
log.debug("instantiated session factory");
if ( settings.isAutoCreateSchema() ) new SchemaExport(cfg, settings).create(false, true);
if ( settings.isAutoUpdateSchema() ) new SchemaUpdate(cfg, settings).execute(false, true);
if ( settings.isAutoValidateSchema() ) new SchemaValidator(cfg, settings).validate();
if ( settings.isAutoDropSchema() ) schemaExport = new SchemaExport(cfg, settings);
if ( settings.getTransactionManagerLookup()!=null ) {
log.debug("obtaining JTA TransactionManager");
transactionManager = settings.getTransactionManagerLookup().getTransactionManager(properties);
}
else {
if ( settings.getTransactionFactory().isTransactionManagerRequired() ) {
throw new HibernateException("The chosen transaction strategy requires access to the JTA TransactionManager");
}
transactionManager = null;
}
currentSessionContext = buildCurrentSessionContext();
if ( settings.isQueryCacheEnabled() ) {
updateTimestampsCache = new UpdateTimestampsCache(settings, properties);
queryCache = settings.getQueryCacheFactory()
.getQueryCache(null, updateTimestampsCache, settings, properties);
queryCaches = new HashMap();
allCacheRegions.put( updateTimestampsCache.getRegionName(), updateTimestampsCache.getCache() );
allCacheRegions.put( queryCache.getRegionName(), queryCache.getCache() );
}
else {
updateTimestampsCache = null;
queryCache = null;
queryCaches = null;
}
//checking for named queries
Map errors = checkNamedQueries();
if ( !errors.isEmpty() ) {
Set keys = errors.keySet();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -