📄 sessionfactoryimpl.java
字号:
//$Id: SessionFactoryImpl.java 11398 2007-04-10 14:54:07Z steve.ebersole@jboss.com $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.slf4j.Logger;import org.slf4j.LoggerFactory;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.ObjectNotFoundException;import org.hibernate.QueryException;import org.hibernate.SessionFactory;import org.hibernate.StatelessSession;import org.hibernate.SessionFactoryObserver;import org.hibernate.cache.CacheKey;import org.hibernate.cache.CollectionRegion;import org.hibernate.cache.EntityRegion;import org.hibernate.cache.QueryCache;import org.hibernate.cache.Region;import org.hibernate.cache.UpdateTimestampsCache;import org.hibernate.cache.access.AccessType;import org.hibernate.cache.access.CollectionRegionAccessStrategy;import org.hibernate.cache.access.EntityRegionAccessStrategy;import org.hibernate.cache.impl.CacheDataDescriptionImpl;import org.hibernate.cfg.Configuration;import org.hibernate.cfg.Environment;import org.hibernate.cfg.Settings;import org.hibernate.connection.ConnectionProvider;import org.hibernate.context.CurrentSessionContext;import org.hibernate.context.JTASessionContext;import org.hibernate.context.ManagedSessionContext;import org.hibernate.context.ThreadLocalSessionContext;import org.hibernate.dialect.Dialect;import org.hibernate.dialect.function.SQLFunctionRegistry;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.sql.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.proxy.EntityNotFoundDelegate;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;/** * 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 static final Logger log = LoggerFactory.getLogger(SessionFactoryImpl.class); private static final IdentifierGenerator UUID_GENERATOR = new UUIDHexGenerator(); 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 transient EntityNotFoundDelegate entityNotFoundDelegate; private final transient SQLFunctionRegistry sqlFunctionRegistry; private final transient SessionFactoryObserver observer; private final QueryPlanCache queryPlanCache = new QueryPlanCache( this ); private transient boolean isClosed = false; public SessionFactoryImpl( Configuration cfg, Mapping mapping, Settings settings, EventListeners listeners, SessionFactoryObserver observer) throws HibernateException { log.info("building session factory"); this.properties = new Properties(); this.properties.putAll( cfg.getProperties() ); this.interceptor = cfg.getInterceptor(); this.settings = settings; this.sqlFunctionRegistry = new SQLFunctionRegistry(settings.getDialect(), cfg.getSqlFunctions()); this.eventListeners = listeners; this.observer = observer != null ? observer : new SessionFactoryObserver() { public void sessionFactoryCreated(SessionFactory factory) { } public void sessionFactoryClosed(SessionFactory factory) { } }; 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.getRegionFactory().start( settings, 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 ); } } /////////////////////////////////////////////////////////////////////// // Prepare persisters and link them up with their cache // region/access-strategy final String cacheRegionPrefix = settings.getCacheRegionPrefix() == null ? "" : settings.getCacheRegionPrefix() + "."; entityPersisters = new HashMap(); Map entityAccessStrategies = new HashMap(); Map classMeta = new HashMap(); classes = cfg.getClassMappings(); while ( classes.hasNext() ) { final PersistentClass model = (PersistentClass) classes.next(); model.prepareTemporaryTables( mapping, settings.getDialect() ); final String cacheRegionName = cacheRegionPrefix + model.getRootClass().getCacheRegionName(); // cache region is defined by the root-class in the hierarchy... EntityRegionAccessStrategy accessStrategy = ( EntityRegionAccessStrategy ) entityAccessStrategies.get( cacheRegionName ); if ( accessStrategy == null && settings.isSecondLevelCacheEnabled() ) { final AccessType accessType = AccessType.parse( model.getCacheConcurrencyStrategy() ); if ( accessType != null ) { log.trace( "Building cache for entity data [" + model.getEntityName() + "]" ); EntityRegion entityRegion = settings.getRegionFactory().buildEntityRegion( cacheRegionName, properties, CacheDataDescriptionImpl.decode( model ) ); accessStrategy = entityRegion.buildAccessStrategy( accessType ); entityAccessStrategies.put( cacheRegionName, accessStrategy ); allCacheRegions.put( cacheRegionName, entityRegion ); } } EntityPersister cp = PersisterFactory.createClassPersister( model, accessStrategy, 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(); final String cacheRegionName = cacheRegionPrefix + model.getCacheRegionName(); final AccessType accessType = AccessType.parse( model.getCacheConcurrencyStrategy() ); CollectionRegionAccessStrategy accessStrategy = null; if ( accessType != null && settings.isSecondLevelCacheEnabled() ) { log.trace( "Building cache for collection data [" + model.getRole() + "]" ); CollectionRegion collectionRegion = settings.getRegionFactory().buildCollectionRegion( cacheRegionName, properties, CacheDataDescriptionImpl.decode( model ) ); accessStrategy = collectionRegion.buildAccessStrategy( accessType ); entityAccessStrategies.put( cacheRegionName, accessStrategy ); allCacheRegions.put( cacheRegionName, collectionRegion ); } CollectionPersister persister = PersisterFactory.createCollectionPersister( cfg, model, accessStrategy, 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.getRegion().getName(), updateTimestampsCache.getRegion() ); allCacheRegions.put( queryCache.getRegion().getName(), queryCache.getRegion() ); } else { updateTimestampsCache = null; queryCache = null; queryCaches = null; } //checking for named queries if ( settings.isNamedQueryStartupCheckingEnabled() ) { Map errors = checkNamedQueries(); if ( !errors.isEmpty() ) { Set keys = errors.keySet();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -