1 package org.hibernate.impl; 3 4 import java.io.IOException ; 5 import java.io.InvalidObjectException ; 6 import java.io.ObjectInputStream ; 7 import java.io.ObjectOutputStream ; 8 import java.io.ObjectStreamException ; 9 import java.io.Serializable ; 10 import java.sql.Connection ; 11 import java.util.ArrayList ; 12 import java.util.Collections ; 13 import java.util.HashMap ; 14 import java.util.Hashtable ; 15 import java.util.Iterator ; 16 import java.util.Map ; 17 import java.util.Properties ; 18 import java.util.Set ; 19 import java.util.HashSet ; 20 21 import javax.naming.NamingException ; 22 import javax.naming.Reference ; 23 import javax.naming.StringRefAddr ; 24 import javax.transaction.Synchronization ; 25 import javax.transaction.Transaction ; 26 import javax.transaction.TransactionManager ; 27 28 import net.sf.cglib.core.KeyFactory; 29 30 import org.apache.commons.collections.ReferenceMap; 31 import org.apache.commons.logging.Log; 32 import org.apache.commons.logging.LogFactory; 33 import org.hibernate.AssertionFailure; 34 import org.hibernate.ConnectionReleaseMode; 35 import org.hibernate.EntityMode; 36 import org.hibernate.HibernateException; 37 import org.hibernate.Interceptor; 38 import org.hibernate.MappingException; 39 import org.hibernate.QueryException; 40 import org.hibernate.SessionFactory; 41 import org.hibernate.StatelessSession; 42 import org.hibernate.cache.Cache; 43 import org.hibernate.cache.CacheConcurrencyStrategy; 44 import org.hibernate.cache.CacheFactory; 45 import org.hibernate.cache.CacheKey; 46 import org.hibernate.cache.QueryCache; 47 import org.hibernate.cache.UpdateTimestampsCache; 48 import org.hibernate.cfg.Configuration; 49 import org.hibernate.cfg.Settings; 50 import org.hibernate.connection.ConnectionProvider; 51 import org.hibernate.dialect.Dialect; 52 import org.hibernate.engine.FilterDefinition; 53 import org.hibernate.engine.Mapping; 54 import org.hibernate.engine.NamedQueryDefinition; 55 import org.hibernate.engine.NamedSQLQueryDefinition; 56 import org.hibernate.engine.SessionFactoryImplementor; 57 import org.hibernate.engine.ResultSetMappingDefinition; 58 import org.hibernate.event.SessionEventListenerConfig; 59 import org.hibernate.exception.SQLExceptionConverter; 60 import org.hibernate.hql.FilterTranslator; 61 import org.hibernate.hql.QuerySplitter; 62 import org.hibernate.hql.QueryTranslator; 63 import org.hibernate.id.IdentifierGenerator; 64 import org.hibernate.id.UUIDHexGenerator; 65 import org.hibernate.jdbc.BatcherFactory; 66 import org.hibernate.mapping.Collection; 67 import org.hibernate.mapping.PersistentClass; 68 import org.hibernate.mapping.RootClass; 69 import org.hibernate.metadata.ClassMetadata; 70 import org.hibernate.metadata.CollectionMetadata; 71 import org.hibernate.persister.PersisterFactory; 72 import org.hibernate.persister.collection.CollectionPersister; 73 import org.hibernate.persister.entity.EntityPersister; 74 import org.hibernate.persister.entity.Queryable; 75 import org.hibernate.pretty.MessageHelper; 76 import org.hibernate.stat.Statistics; 77 import org.hibernate.stat.StatisticsImpl; 78 import org.hibernate.stat.StatisticsImplementor; 79 import org.hibernate.tool.hbm2ddl.SchemaExport; 80 import org.hibernate.tool.hbm2ddl.SchemaUpdate; 81 import org.hibernate.transaction.TransactionFactory; 82 import org.hibernate.type.Type; 83 import org.hibernate.type.AssociationType; 84 import org.hibernate.util.CollectionHelper; 85 import org.hibernate.util.JTAHelper; 86 import org.hibernate.util.ReflectHelper; 87 88 89 112 public final class SessionFactoryImpl implements SessionFactory, SessionFactoryImplementor { 113 114 private final String name; 115 private final String uuid; 116 117 private final transient Map entityPersisters; 118 private final transient Map classMetadata; 119 private final transient Map collectionPersisters; 120 private final transient Map collectionMetadata; 121 private final transient Map collectionRolesByEntityParticipant; 122 private final transient Map identifierGenerators; 123 private final transient Map namedQueries; 124 private final transient Map namedSqlQueries; 125 private final transient Map sqlResultSetMappings; 126 private final transient Map filters; 127 private final transient Map imports; 128 private final transient Interceptor interceptor; 129 private final transient Settings settings; 130 private final transient Properties properties; 131 private transient SchemaExport schemaExport; 132 private final transient TransactionManager transactionManager; 133 private final transient QueryCache queryCache; 134 private final transient UpdateTimestampsCache updateTimestampsCache; 135 private final transient Map queryCaches; 136 private final transient Map allCacheRegions = new HashMap (); 137 private final transient StatisticsImpl statistics = new StatisticsImpl(this); 138 139 private transient boolean isClosed = false; 140 141 private static final IdentifierGenerator UUID_GENERATOR = new UUIDHexGenerator(); 142 143 private SessionEventListenerConfig sessionEventListenerConfig; 144 145 private transient Map currentSessionMap = new Hashtable (); 146 147 private static final Log log = LogFactory.getLog(SessionFactoryImpl.class); 148 149 public SessionFactoryImpl( 150 Configuration cfg, 151 Mapping mapping, 152 Settings settings, 153 SessionEventListenerConfig listeners) 154 throws HibernateException { 155 156 log.info("building session factory"); 157 158 this.properties = cfg.getProperties(); 159 this.interceptor = cfg.getInterceptor(); 160 this.settings = settings; 161 this.sessionEventListenerConfig = listeners; 162 this.filters = cfg.getFilterDefinitions(); 163 164 if ( log.isDebugEnabled() ) { 165 log.debug("Session factory constructed with filter configurations : " + filters); 166 } 167 168 if ( log.isDebugEnabled() ) log.debug( 169 "instantiating session factory with properties: " + properties 170 ); 171 172 settings.getCacheProvider().start( properties ); 174 175 177 identifierGenerators = new HashMap (); 178 Iterator classes = cfg.getClassMappings(); 179 while ( classes.hasNext() ) { 180 PersistentClass model = (PersistentClass) classes.next(); 181 if ( !model.isInherited() ) { 182 IdentifierGenerator generator = model.getIdentifier().createIdentifierGenerator( 183 settings.getDialect(), 184 settings.getDefaultCatalogName(), 185 settings.getDefaultSchemaName(), 186 (RootClass) model 187 ); 188 identifierGenerators.put( model.getEntityName(), generator ); 189 } 190 } 191 192 194 Map caches = new HashMap (); 195 entityPersisters = new HashMap (); 196 Map classMeta = new HashMap (); 197 classes = cfg.getClassMappings(); 198 while ( classes.hasNext() ) { 199 PersistentClass model = (PersistentClass) classes.next(); 200 model.prepareTemporaryTables( mapping, settings.getDialect() ); 201 String cacheRegion = model.getRootClass().getCacheRegionName(); 202 CacheConcurrencyStrategy cache = (CacheConcurrencyStrategy) caches.get(cacheRegion); 203 if (cache==null) { 204 cache = CacheFactory.createCache( 205 model.getCacheConcurrencyStrategy(), 206 cacheRegion, 207 model.isMutable(), 208 settings, 209 properties 210 ); 211 if (cache!=null) { 212 caches.put(cacheRegion, cache); 213 allCacheRegions.put( cache.getRegionName(), cache.getCache() ); 214 } 215 } 216 EntityPersister cp = PersisterFactory.createClassPersister(model, cache, this, mapping); 217 entityPersisters.put( model.getEntityName(), cp ); 218 classMeta.put( model.getEntityName(), cp.getClassMetadata() ); 219 } 220 classMetadata = Collections.unmodifiableMap(classMeta); 221 222 Map tmpEntityToCollectionRoleMap = new HashMap (); 223 collectionPersisters = new HashMap (); 224 Iterator collections = cfg.getCollectionMappings(); 225 while ( collections.hasNext() ) { 226 Collection model = (Collection) collections.next(); 227 CacheConcurrencyStrategy cache = CacheFactory.createCache( 228 model.getCacheConcurrencyStrategy(), 229 model.getCacheRegionName(), 230 true, 231 settings, 232 properties 233 ); 234 if (cache!=null) allCacheRegions.put( cache.getRegionName(), cache.getCache() ); 235 CollectionPersister persister = PersisterFactory.createCollectionPersister(cfg, model, cache, this); 236 collectionPersisters.put( model.getRole(), persister.getCollectionMetadata() ); 237 Type indexType = persister.getIndexType(); 238 if ( indexType != null && indexType.isAssociationType() && !indexType.isAnyType() ) { 239 String entityName = ( ( AssociationType ) indexType ).getAssociatedEntityName( this ); 240 Set roles = ( Set ) tmpEntityToCollectionRoleMap.get( entityName ); 241 if ( roles == null ) { 242 roles = new HashSet (); 243 tmpEntityToCollectionRoleMap.put( entityName, roles ); 244 } 245 roles.add( persister.getRole() ); 246 } 247 Type elementType = persister.getElementType(); 248 if ( elementType.isAssociationType() && !elementType.isAnyType() ) { 249 String entityName = ( ( AssociationType ) elementType ).getAssociatedEntityName( this ); 250 Set roles = ( Set ) tmpEntityToCollectionRoleMap.get( entityName ); 251 if ( roles == null ) { 252 roles = new HashSet (); 253 tmpEntityToCollectionRoleMap.put( entityName, roles ); 254 } 255 roles.add( persister.getRole() ); 256 } 257 } 258 collectionMetadata = Collections.unmodifiableMap(collectionPersisters); 259 Iterator itr = tmpEntityToCollectionRoleMap.entrySet().iterator(); 260 while ( itr.hasNext() ) { 261 final Map.Entry entry = ( Map.Entry ) itr.next(); 262 entry.setValue( Collections.unmodifiableSet( ( Set ) entry.getValue() ) ); 263 } 264 collectionRolesByEntityParticipant = Collections.unmodifiableMap( tmpEntityToCollectionRoleMap ); 265 266 namedQueries = new HashMap ( cfg.getNamedQueries() ); 269 namedSqlQueries = new HashMap ( cfg.getNamedSQLQueries() ); 270 sqlResultSetMappings = new HashMap ( cfg.getSqlResultSetMappings() ); 271 imports = new HashMap ( cfg.getImports() ); 272 273 Iterator iter = entityPersisters.values().iterator(); 275 while ( iter.hasNext() ) { 276 ( (EntityPersister) iter.next() ).postInstantiate(); 277 } 278 iter = collectionPersisters.values().iterator(); 279 while ( iter.hasNext() ) { 280 ( (CollectionPersister) iter.next() ).postInstantiate(); 281 } 282 283 285 name = settings.getSessionFactoryName(); 286 try { 287 uuid = (String ) UUID_GENERATOR.generate(null, null); 288 } 289 catch (Exception e) { 290 throw new AssertionFailure("Could not generate UUID"); 291 } 292 SessionFactoryObjectFactory.addInstance(uuid, name, this, properties); 293 294 log.debug("instantiated session factory"); 295 296 if ( settings.isAutoCreateSchema() ) new SchemaExport(cfg, settings).create(false, true); 297 if ( settings.isAutoUpdateSchema() ) new SchemaUpdate(cfg, settings).execute(false, true); 298 if ( settings.isAutoDropSchema() ) schemaExport = new SchemaExport(cfg, settings); 299 300 if ( settings.getTransactionManagerLookup()!=null ) { 301 log.debug("obtaining JTA TransactionManager"); 302 transactionManager = settings.getTransactionManagerLookup().getTransactionManager(properties); 303 } 304 else { 305 transactionManager = null; 306 } 307 308 if ( settings.isQueryCacheEnabled() ) { 309 updateTimestampsCache = new UpdateTimestampsCache(settings, properties); 310 queryCache = settings.getQueryCacheFactory() 311 .getQueryCache(null, updateTimestampsCache, settings, properties); 312 queryCaches = new HashMap (); 313 allCacheRegions.put( updateTimestampsCache.getRegionName(), updateTimestampsCache.getCache() ); 314 allCacheRegions.put( queryCache.getRegionName(), queryCache.getCache() ); 315 } 316 else { 317 updateTimestampsCache = null; 318 queryCache = null; 319 queryCaches = null; 320 } 321 322 Map errors = checkNamedQueries(); 324 if ( !errors.isEmpty() ) { 325 Set keys = errors.keySet(); 326 StringBuffer failingQueries = new StringBuffer ("Errors in named queries: "); 327 for ( Iterator iterator = keys.iterator() ; iterator.hasNext() ; ) { 328 String queryName = (String ) iterator.next(); 329 HibernateException e = (HibernateException) errors.get(queryName); 330 failingQueries.append(queryName); 331 if ( iterator.hasNext() ) failingQueries.append(", "); 332 log.error("Error in named query: " + queryName, e); 333 } 334 throw new HibernateException( failingQueries.toString() ); 335 } 336 337 getStatistics().setStatisticsEnabled( settings.isStatisticsEnabled() ); 339 } 340 341 private static final int MAX_STRONG_REF_COUNT = 128; private final transient Object [] strongRefs = new Object [MAX_STRONG_REF_COUNT]; private transient int strongRefIndex = 0; 346 private final transient Map softQueryCache = new ReferenceMap(ReferenceMap.SOFT, ReferenceMap.SOFT) ; 347 349 private static final QueryCacheKeyFactory QUERY_KEY_FACTORY; 351 private static final FilterCacheKeyFactory FILTER_KEY_FACTORY; 352 static { 353 QUERY_KEY_FACTORY = (QueryCacheKeyFactory) KeyFactory.create(QueryCacheKeyFactory.class); 354 FILTER_KEY_FACTORY = (FilterCacheKeyFactory) KeyFactory.create(FilterCacheKeyFactory.class); 355 } 356 357 static interface QueryCacheKeyFactory { 358 Object newInstance(String query, boolean scalar); 360 } 361 362 static interface FilterCacheKeyFactory { 363 Object newInstance(String role, String query, boolean scalar); 365 } 366 367 private synchronized Object get(Object key) { 369 Object result = softQueryCache.get(key); 370 if( result != null ) { 371 strongRefs[ ++strongRefIndex % MAX_STRONG_REF_COUNT ] = result; 372 } 373 return result; 374 } 375 376 private void put(Object key, Object value) { 377 softQueryCache.put(key, value); 378 strongRefs[ ++strongRefIndex % MAX_STRONG_REF_COUNT ] = value; 379 } 380 381 private synchronized QueryTranslator[] createQueryTranslators( 382 String [] concreteQueryStrings, 383 Object cacheKey, 384 Map enabledFilters 385 ) { 386 final int length = concreteQueryStrings.length; 387 final QueryTranslator[] queries = new QueryTranslator[length]; 388 for ( int i=0; i<length; i++ ) { 389 queries[i] = settings.getQueryTranslatorFactory() 390 .createQueryTranslator( concreteQueryStrings[i], enabledFilters, this ); 391 } 392 if (cacheKey != null) put(cacheKey, queries); 393 return queries; 394 } 395 396 private synchronized FilterTranslator createFilterTranslator( 397 String filterString, 398 Object cacheKey, 399 Map enabledFilters 400 ) { 401 final FilterTranslator filter = settings.getQueryTranslatorFactory() 402 .createFilterTranslator(filterString, enabledFilters, this); 403 if (cacheKey != null) put(cacheKey, filter); 404 return filter; 405 } 406 407 private Map checkNamedQueries() throws HibernateException { 408 Map errors = new HashMap (); 410 Set names = namedQueries.keySet(); 411 log.info("Checking " + namedQueries.size() + " named queries"); 412 for ( Iterator iterator = names.iterator(); iterator.hasNext(); ) { 413 String queryName = (String ) iterator.next(); 414 NamedQueryDefinition q = (NamedQueryDefinition) namedQueries.get(queryName); 415 416 try { 418 log.debug("Checking named query: " + queryName); 419 getQuery( q.getQueryString(), false, CollectionHelper.EMPTY_MAP ); 421 } 422 catch (QueryException e) { 423 errors.put(queryName, e); 424 } 425 catch (MappingException e) { 426 errors.put(queryName, e); 427 } 428 } 429 430 return errors; 431 } 432 433 public QueryTranslator[] getQuery(String queryString, boolean shallow, Map enabledFilters) 434 throws QueryException, MappingException { 435 436 Object cacheKey = null; 439 QueryTranslator[] queries = null; 440 441 if ( enabledFilters == null || enabledFilters.isEmpty() ) { 442 cacheKey = QUERY_KEY_FACTORY.newInstance(queryString, shallow); 443 queries = (QueryTranslator[]) get(cacheKey); 444 } 445 446 451 if ( queries==null ) { 452 String [] concreteQueryStrings = QuerySplitter.concreteQueries(queryString, this); 455 queries = createQueryTranslators(concreteQueryStrings, cacheKey, enabledFilters); 456 } 457 for ( int i=0; i<queries.length; i++) { 458 queries[i].compile( settings.getQuerySubstitutions(), shallow ); 460 } 461 return queries; 463 464 } 465 466 public FilterTranslator getFilter( 467 String filterString, 468 String collectionRole, 469 boolean scalar, 470 Map enabledFilters) 471 throws QueryException, MappingException { 472 473 Object cacheKey = null; 474 FilterTranslator filter = null; 475 476 if ( enabledFilters == null || enabledFilters.isEmpty() ) { 477 cacheKey = FILTER_KEY_FACTORY.newInstance(collectionRole, filterString, scalar); 478 filter = (FilterTranslator) get(cacheKey); 479 } 480 481 if ( filter==null ) { 482 filter = createFilterTranslator(filterString, cacheKey, enabledFilters); 483 } 484 filter.compile( collectionRole, settings.getQuerySubstitutions(), scalar ); 486 return filter; 488 489 } 490 491 public StatelessSession openStatelessSession() { 492 return new StatelessSessionImpl( null, this ); 493 } 494 495 public StatelessSession openStatelessSession(Connection connection) { 496 return new StatelessSessionImpl( connection, this ); 497 } 498 499 private SessionImpl openSession( 500 Connection connection, 501 boolean autoClose, 502 long timestamp, 503 Interceptor sessionLocalInterceptor 504 ) { 505 return new SessionImpl( 506 connection, 507 this, 508 autoClose, 509 timestamp, 510 sessionLocalInterceptor, 511 sessionEventListenerConfig, 512 settings.getDefaultEntityMode(), 513 settings.isFlushBeforeCompletionEnabled(), 514 settings.isAutoCloseSessionEnabled(), 515 settings.getConnectionReleaseMode() 516 ); 517 } 518 519 public org.hibernate.classic.Session openSession(Connection connection, Interceptor sessionLocalInterceptor) { 520 return openSession(connection, false, Long.MIN_VALUE, sessionLocalInterceptor); 521 } 522 523 public org.hibernate.classic.Session openSession(Interceptor sessionLocalInterceptor) 524 throws HibernateException { 525 long timestamp = settings.getCacheProvider().nextTimestamp(); 530 return openSession( null, true, timestamp, sessionLocalInterceptor ); 531 } 532 533 public org.hibernate.classic.Session openSession(Connection connection) { 534 return openSession(connection, interceptor); } 536 537 public org.hibernate.classic.Session openSession() throws HibernateException { 538 return openSession(interceptor); 539 } 540 541 public org.hibernate.classic.Session openTemporarySession() throws HibernateException { 542 return new SessionImpl( 543 null, 544 this, 545 true, 546 settings.getCacheProvider().nextTimestamp(), 547 interceptor, 548 sessionEventListenerConfig, 549 settings.getDefaultEntityMode(), 550 false, 551 false, 552 ConnectionReleaseMode.AFTER_STATEMENT 553 ); 554 } 555 556 public org.hibernate.classic.Session getCurrentSession() throws HibernateException { 557 if ( transactionManager == null ) { 558 throw new HibernateException( "No TransactionManagerLookup specified" ); 559 } 560 561 Transaction txn = null; 562 try { 563 txn = transactionManager.getTransaction(); 564 if ( txn == null ) { 565 throw new HibernateException( "Unable to locate current JTA transaction" ); 566 } 567 if ( !JTAHelper.isInProgress( txn.getStatus() ) ) { 568 throw new HibernateException( "Current transaction is not in progress" ); 572 } 573 } 574 catch( HibernateException e ) { 575 throw e; 576 } 577 catch( Throwable t ) { 578 throw new HibernateException( "Problem locating/validating JTA transaction", t ); 579 } 580 581 org.hibernate.classic.Session currentSession = (org.hibernate.classic.Session) currentSessionMap.get( txn ); 582 583 if ( currentSession == null ) { 584 currentSession = new SessionImpl( 585 null, 586 this, 587 true, 588 settings.getCacheProvider().nextTimestamp(), 589 interceptor, 590 sessionEventListenerConfig, 591 settings.getDefaultEntityMode(), 592 true, 593 true, 594 ConnectionReleaseMode.AFTER_STATEMENT 595 ); 596 try { 597 txn.registerSynchronization( 598 new CurrentSessionCleanupSynch( txn, this ) 599 ); 600 } 601 catch( Throwable t ) { 602 try { 603 currentSession.close(); 604 } 605 catch( Throwable ignore ) { 606 log.debug( "Unable to release generated current-session on failed synch registration", ignore ); 607 } 608 throw new HibernateException( "Unable to register cleanup Synchronization with TransactionManager" ); 609 } 610 611 currentSessionMap.put( txn, currentSession ); 612 } 613 614 return currentSession; 615 } 616 617 public EntityPersister getEntityPersister(String entityName) throws MappingException { 618 EntityPersister result = (EntityPersister) entityPersisters.get(entityName); 619 if (result==null) { 620 throw new MappingException( "Unknown entity: " + entityName ); 621 } 622 return result; 623 } 624 625 public CollectionPersister getCollectionPersister(String role) throws MappingException { 626 CollectionPersister result = (CollectionPersister) collectionPersisters.get(role); 627 if (result==null) { 628 throw new MappingException( "Unknown collection role: " + role ); 629 } 630 return result; 631 } 632 633 public Settings getSettings() { 634 return settings; 635 } 636 637 public Dialect getDialect() { 638 return settings.getDialect(); 639 } 640 641 public TransactionFactory getTransactionFactory() { 642 return settings.getTransactionFactory(); 643 } 644 645 public TransactionManager getTransactionManager() { 646 return transactionManager; 647 } 648 649 public SQLExceptionConverter getSQLExceptionConverter() { 650 return settings.getSQLExceptionConverter(); 651 } 652 653 public Set getCollectionRolesByEntityParticipant(String entityName) { 654 return ( Set ) collectionRolesByEntityParticipant.get( entityName ); 655 } 656 657 public Reference getReference() throws NamingException { 659 log.debug("Returning a Reference to the SessionFactory"); 660 return new Reference ( 661 SessionFactoryImpl.class.getName(), 662 new StringRefAddr ("uuid", uuid), 663 SessionFactoryObjectFactory.class.getName(), 664 null 665 ); 666 } 667 668 private Object readResolve() throws ObjectStreamException { 669 log.trace("Resolving serialized SessionFactory"); 670 Object result = SessionFactoryObjectFactory.getInstance(uuid); 672 if (result==null) { 673 result = SessionFactoryObjectFactory.getNamedInstance(name); 676 if (result==null) { 677 throw new InvalidObjectException ("Could not find a SessionFactory named: " + name); 678 } 679 else { 680 log.debug("resolved SessionFactory by name"); 681 } 682 } 683 else { 684 log.debug("resolved SessionFactory by uid"); 685 } 686 return result; 687 } 688 689 public NamedQueryDefinition getNamedQuery(String queryName) { 690 return (NamedQueryDefinition) namedQueries.get(queryName); 691 } 692 693 public NamedSQLQueryDefinition getNamedSQLQuery(String queryName) { 694 return (NamedSQLQueryDefinition) namedSqlQueries.get(queryName); 695 } 696 697 public ResultSetMappingDefinition getResultSetMapping(String resultSetName) { 698 return (ResultSetMappingDefinition) sqlResultSetMappings.get(resultSetName); 699 } 700 701 public Type getIdentifierType(String className) throws MappingException { 702 return getEntityPersister(className).getIdentifierType(); 703 } 704 public String getIdentifierPropertyName(String className) throws MappingException { 705 return getEntityPersister(className).getIdentifierPropertyName(); 706 } 707 708 private final void readObject(ObjectInputStream in) throws IOException , ClassNotFoundException { 709 log.trace("deserializing"); 710 in.defaultReadObject(); 711 log.debug("deserialized: " + uuid); 712 } 713 private final void writeObject(ObjectOutputStream out) throws IOException { 714 log.debug("serializing: " + uuid); 715 out.defaultWriteObject(); 716 log.trace("serialized"); 717 } 718 719 public Type[] getReturnTypes(String queryString) throws HibernateException { 720 return getRepresentativeQuery(queryString).getReturnTypes(); 721 } 722 723 public String [] getReturnAliases(String queryString) throws HibernateException { 724 return getRepresentativeQuery(queryString).getReturnAliases(); 725 } 726 727 private QueryTranslator getRepresentativeQuery(String queryString) throws HibernateException { 728 String [] queries = QuerySplitter.concreteQueries(queryString, this); 729 if ( queries.length==0 ) throw new HibernateException("Query does not refer to any persistent classes: " + queryString); 730 return getQuery( queries[0], true, CollectionHelper.EMPTY_MAP )[0]; 731 } 732 733 public ClassMetadata getClassMetadata(Class persistentClass) throws HibernateException { 734 return getClassMetadata( persistentClass.getName() ); 735 } 736 737 public CollectionMetadata getCollectionMetadata(String roleName) throws HibernateException { 738 return (CollectionMetadata) collectionMetadata.get(roleName); 739 } 740 741 public ClassMetadata getClassMetadata(String entityName) throws HibernateException { 742 return (ClassMetadata) classMetadata.get(entityName); 743 } 744 745 750 public String [] getImplementors(String className) throws MappingException { 751 752 final Class clazz; 753 try { 754 clazz = ReflectHelper.classForName(className); 755 } 756 catch (ClassNotFoundException cnfe) { 757 return new String [] { className }; } 759 760 ArrayList results = new ArrayList (); 761 Iterator iter = entityPersisters.values().iterator(); 762 while ( iter.hasNext() ) { 763 EntityPersister testPersister = (EntityPersister) iter.next(); 765 if ( testPersister instanceof Queryable ) { 766 Queryable testQueryable = (Queryable) testPersister; 767 String testClassName = testQueryable.getEntityName(); 768 boolean isMappedClass = className.equals(testClassName); 769 if ( testQueryable.isExplicitPolymorphism() ) { 770 if (isMappedClass) return new String [] { className }; } 772 else { 773 if (isMappedClass) { 774 results.add(testClassName); 775 } 776 else { 777 final Class mappedClass = testQueryable.getMappedClass( EntityMode.POJO ); 778 if ( mappedClass!=null && clazz.isAssignableFrom( mappedClass ) ) { 779 final boolean assignableSuperclass; 780 if ( testQueryable.isInherited() ) { 781 Class mappedSuperclass = getEntityPersister( testQueryable.getMappedSuperclass() ).getMappedClass( EntityMode.POJO); 782 assignableSuperclass = clazz.isAssignableFrom(mappedSuperclass); 783 } 784 else { 785 assignableSuperclass = false; 786 } 787 if (!assignableSuperclass) results.add(testClassName); 788 } 789 } 790 } 791 } 792 } 793 return (String []) results.toArray( new String [ results.size() ] ); 794 } 795 796 public String getImportedClassName(String className) { 797 String result = (String ) imports.get(className); 798 if (result==null) { 799 try { 800 ReflectHelper.classForName(className); 801 return className; 802 } 803 catch (ClassNotFoundException cnfe) { 804 return null; 805 } 806 } 807 else { 808 return result; 809 } 810 } 811 812 public Map getAllClassMetadata() throws HibernateException { 813 return classMetadata; 814 } 815 816 public Map getAllCollectionMetadata() throws HibernateException { 817 return collectionMetadata; 818 } 819 820 829 public void close() throws HibernateException { 830 831 log.info("closing"); 832 833 isClosed = true; 834 835 Iterator iter = entityPersisters.values().iterator(); 836 while ( iter.hasNext() ) { 837 EntityPersister p = (EntityPersister) iter.next(); 838 if ( p.hasCache() ) p.getCache().destroy(); 839 } 840 841 iter = collectionPersisters.values().iterator(); 842 while ( iter.hasNext() ) { 843 CollectionPersister p = (CollectionPersister) iter.next(); 844 if ( p.hasCache() ) p.getCache().destroy(); 845 } 846 847 if ( settings.isQueryCacheEnabled() ) { 848 queryCache.destroy(); 849 850 iter = queryCaches.values().iterator(); 851 while ( iter.hasNext() ) { 852 QueryCache cache = (QueryCache) iter.next(); 853 cache.destroy(); 854 } 855 updateTimestampsCache.destroy(); 856 } 857 858 settings.getCacheProvider().stop(); 859 860 try { 861 settings.getConnectionProvider().close(); 862 } 863 finally { 864 SessionFactoryObjectFactory.removeInstance(uuid, name, properties); 865 } 866 867 if ( settings.isAutoDropSchema() ) schemaExport.drop(false, true); 868 869 } 870 871 public void evictEntity(String entityName, Serializable id) throws HibernateException { 872 EntityPersister p = getEntityPersister(entityName); 873 if ( p.hasCache() ) { 874 if ( log.isDebugEnabled() ) { 875 log.debug( "evicting second-level cache: " + MessageHelper.infoString(p, id, this) ); 876 } 877 CacheKey cacheKey = new CacheKey( id, p.getIdentifierType(), p.getRootEntityName(), EntityMode.POJO, this ); 878 p.getCache().remove( cacheKey ); 879 } 880 } 881 882 public void evictEntity(String entityName) throws HibernateException { 883 EntityPersister p = getEntityPersister(entityName); 884 if ( p.hasCache() ) { 885 if ( log.isDebugEnabled() ) { 886 log.debug( "evicting second-level cache: " + p.getEntityName() ); 887 } 888 p.getCache().clear(); 889 } 890 } 891 892 public void evict(Class persistentClass, Serializable id) throws HibernateException { 893 EntityPersister p = getEntityPersister( persistentClass.getName() ); 894 if ( p.hasCache() ) { 895 if ( log.isDebugEnabled() ) { 896 log.debug( "evicting second-level cache: " + MessageHelper.infoString(p, id, this) ); 897 } 898 CacheKey cacheKey = new CacheKey( id, p.getIdentifierType(), p.getRootEntityName(), EntityMode.POJO, this ); 899 p.getCache().remove( cacheKey ); 900 } 901 } 902 903 public void evict(Class persistentClass) throws HibernateException { 904 EntityPersister p = getEntityPersister( persistentClass.getName() ); 905 if ( p.hasCache() ) { 906 if ( log.isDebugEnabled() ) { 907 log.debug( "evicting second-level cache: " + p.getEntityName() ); 908 } 909 p.getCache().clear(); 910 } 911 } 912 913 public void evictCollection(String roleName, Serializable id) throws HibernateException { 914 CollectionPersister p = getCollectionPersister(roleName); 915 if ( p.hasCache() ) { 916 if ( log.isDebugEnabled() ) { 917 log.debug( "evicting second-level cache: " + MessageHelper.collectionInfoString(p, id, this) ); 918 } 919 CacheKey cacheKey = new CacheKey( id, p.getKeyType(), p.getRole(), EntityMode.POJO, this ); 920 p.getCache().remove( cacheKey ); 921 } 922 } 923 924 public void evictCollection(String roleName) throws HibernateException { 925 CollectionPersister p = getCollectionPersister(roleName); 926 if ( p.hasCache() ) { 927 if ( log.isDebugEnabled() ) log.debug( "evicting second-level cache: " + p.getRole() ); 928 p.getCache().clear(); 929 } 930 } 931 932 public Type getReferencedPropertyType(String className, String propertyName) 933 throws MappingException { 934 return getEntityPersister(className).getPropertyType(propertyName); 935 } 936 937 public ConnectionProvider getConnectionProvider() { 938 return settings.getConnectionProvider(); 939 } 940 941 public UpdateTimestampsCache getUpdateTimestampsCache() { 942 return updateTimestampsCache; 943 } 944 945 public QueryCache getQueryCache() { 946 return queryCache; 947 } 948 949 public QueryCache getQueryCache(String cacheRegion) throws HibernateException { 950 if (cacheRegion==null) { 951 return getQueryCache(); 952 } 953 954 if ( !settings.isQueryCacheEnabled() ) { 955 return null; 956 } 957 958 synchronized (allCacheRegions) { 959 QueryCache currentQueryCache = (QueryCache) queryCaches.get(cacheRegion); 960 if (currentQueryCache==null) { 961 currentQueryCache = settings.getQueryCacheFactory() 962 .getQueryCache(cacheRegion, updateTimestampsCache, settings, properties); 963 queryCaches.put(cacheRegion, currentQueryCache); 964 allCacheRegions.put( currentQueryCache.getRegionName(), currentQueryCache.getCache() ); 965 } 966 return currentQueryCache; 967 } 968 } 969 970 public Cache getSecondLevelCacheRegion(String regionName) { 971 synchronized (allCacheRegions) { 972 return (Cache) allCacheRegions.get(regionName); 973 } 974 } 975 976 public Map getAllSecondLevelCacheRegions() { 977 synchronized (allCacheRegions) { 978 return new HashMap (allCacheRegions); 979 } 980 } 981 982 public boolean isClosed() { 983 return isClosed; 984 } 985 986 public Statistics getStatistics() { 987 return statistics; 988 } 989 990 public StatisticsImplementor getStatisticsImplementor() { 991 return statistics; 992 } 993 994 public void evictQueries() throws HibernateException { 995 if ( settings.isQueryCacheEnabled() ) { 996 queryCache.clear(); 997 } 998 } 999 1000 public void evictQueries(String cacheRegion) throws HibernateException { 1001 if (cacheRegion==null) { 1002 throw new NullPointerException ("use the zero-argument form to evict the default query cache"); 1003 } 1004 else { 1005 synchronized (allCacheRegions) { 1006 if ( settings.isQueryCacheEnabled() ) { 1007 QueryCache currentQueryCache = (QueryCache) queryCaches.get(cacheRegion); 1008 if (currentQueryCache!=null) currentQueryCache.clear(); 1009 } 1010 } 1011 } 1012 } 1013 1014 public FilterDefinition getFilterDefinition(String filterName) throws IllegalArgumentException { 1015 FilterDefinition def = (FilterDefinition) filters.get(filterName); 1016 if (def == null) { 1017 throw new IllegalArgumentException ("No such filter configured [" + filterName + "]"); 1019 } 1020 return def; 1021 } 1022 1023 public BatcherFactory getBatcherFactory() { 1024 return settings.getBatcherFactory(); 1025 } 1026 1027 public IdentifierGenerator getIdentifierGenerator(String rootEntityName) { 1028 return (IdentifierGenerator) identifierGenerators.get(rootEntityName); 1029 } 1030 1031 static class CurrentSessionCleanupSynch implements Synchronization { 1032 private Transaction txn; 1033 private SessionFactoryImpl impl; 1034 1035 public CurrentSessionCleanupSynch(Transaction txn, SessionFactoryImpl impl) { 1036 this.txn = txn; 1037 this.impl = impl; 1038 } 1039 1040 public void beforeCompletion() { 1041 } 1042 1043 public void afterCompletion(int i) { 1044 impl.currentSessionMap.remove( txn ); 1045 } 1046 } 1047} 1048 | Popular Tags |