📄 sessionfactoryimpl.java
字号:
//$Id: SessionFactoryImpl.java,v 1.70 2005/04/13 20:46:19 steveebersole Exp $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.Hashtable;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.Synchronization;import javax.transaction.SystemException;import javax.transaction.Transaction;import javax.transaction.TransactionManager;import net.sf.cglib.core.KeyFactory;import org.apache.commons.collections.ReferenceMap;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.hibernate.AssertionFailure;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.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.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.SessionFactoryImplementor;import org.hibernate.event.SessionEventListenerConfig;import org.hibernate.exception.SQLExceptionConverter;import org.hibernate.hql.FilterTranslator;import org.hibernate.hql.QuerySplitter;import org.hibernate.hql.QueryTranslator;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.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.transaction.TransactionFactory;import org.hibernate.type.Type;import org.hibernate.util.CollectionHelper;import org.hibernate.util.JTAHelper;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 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 identifierGenerators; private final transient Map namedQueries; private final transient Map namedSqlQueries; 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 static final IdentifierGenerator UUID_GENERATOR = new UUIDHexGenerator(); private SessionEventListenerConfig sessionEventListenerConfig; private transient Map currentSessionMap; private static final Log log = LogFactory.getLog(SessionFactoryImpl.class); public SessionFactoryImpl( Configuration cfg, Mapping mapping, Settings settings, SessionEventListenerConfig listeners) throws HibernateException { log.info("building session factory"); this.properties = cfg.getProperties(); this.interceptor = cfg.getInterceptor(); this.settings = settings; this.sessionEventListenerConfig = listeners; this.filters = 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(), model.getEntityName() ); 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(); 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); 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() ); } collectionMetadata = Collections.unmodifiableMap(collectionPersisters); //Named Queries: // TODO: precompile and cache named queries namedQueries = new HashMap( cfg.getNamedQueries() ); namedSqlQueries = new HashMap( cfg.getNamedSQLQueries() ); 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).create(false, true); if ( settings.isAutoUpdateSchema() ) new SchemaUpdate(cfg).execute(false, true); if ( settings.isAutoDropSchema() ) schemaExport = new SchemaExport(cfg); if ( settings.getTransactionManagerLookup()!=null ) { log.debug("obtaining JTA TransactionManager"); transactionManager = settings.getTransactionManagerLookup().getTransactionManager(properties); } else { transactionManager = null; } 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(); StringBuffer failingQueries = new StringBuffer("Errors in named queries: "); for ( Iterator iterator = keys.iterator() ; iterator.hasNext() ; ) { String queryName = (String) iterator.next(); HibernateException e = (HibernateException) errors.get(queryName); failingQueries.append(queryName); if ( iterator.hasNext() ) failingQueries.append(", "); log.error("Error in named query: " + queryName, e); } throw new HibernateException( failingQueries.toString() ); } //stats getStatistics().setStatisticsEnabled( settings.isStatisticsEnabled() ); } // Emulates constant time LRU/MRU algorithms for cache // It is better to hold strong references on some (LRU/MRU) queries private static final int MAX_STRONG_REF_COUNT = 128; //TODO: configurable? private final transient Object[] strongRefs = new Object[MAX_STRONG_REF_COUNT]; //strong reference to MRU queries private transient int strongRefIndex = 0; private final transient Map softQueryCache = new ReferenceMap(ReferenceMap.SOFT, ReferenceMap.SOFT) ; // both keys and values may be soft since value keeps a hard ref to the key (and there is a hard ref to MRU values) //returns generated class instance private static final QueryCacheKeyFactory QUERY_KEY_FACTORY; private static final FilterCacheKeyFactory FILTER_KEY_FACTORY; static { QUERY_KEY_FACTORY = (QueryCacheKeyFactory) KeyFactory.create(QueryCacheKeyFactory.class); FILTER_KEY_FACTORY = (FilterCacheKeyFactory) KeyFactory.create(FilterCacheKeyFactory.class); } static interface QueryCacheKeyFactory { //Will not recalculate hashKey for constant queries Object newInstance(String query, boolean scalar);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -