1 16 17 package org.springframework.orm.hibernate; 18 19 import java.io.File ; 20 import java.io.IOException ; 21 import java.sql.Connection ; 22 import java.sql.SQLException ; 23 import java.sql.Statement ; 24 import java.util.Properties ; 25 26 import javax.sql.DataSource ; 27 import javax.transaction.TransactionManager ; 28 29 import net.sf.hibernate.HibernateException; 30 import net.sf.hibernate.Interceptor; 31 import net.sf.hibernate.Session; 32 import net.sf.hibernate.SessionFactory; 33 import net.sf.hibernate.cfg.Configuration; 34 import net.sf.hibernate.cfg.Environment; 35 import net.sf.hibernate.cfg.NamingStrategy; 36 import net.sf.hibernate.dialect.Dialect; 37 import net.sf.hibernate.tool.hbm2ddl.DatabaseMetadata; 38 import org.apache.commons.logging.Log; 39 import org.apache.commons.logging.LogFactory; 40 41 import org.springframework.beans.factory.DisposableBean; 42 import org.springframework.beans.factory.FactoryBean; 43 import org.springframework.beans.factory.InitializingBean; 44 import org.springframework.core.io.ClassPathResource; 45 import org.springframework.core.io.Resource; 46 import org.springframework.dao.DataAccessException; 47 import org.springframework.jdbc.support.JdbcUtils; 48 import org.springframework.jdbc.support.lob.LobHandler; 49 50 81 public class LocalSessionFactoryBean implements FactoryBean, InitializingBean, DisposableBean { 82 83 private static final ThreadLocal configTimeDataSourceHolder = new ThreadLocal (); 84 85 private static final ThreadLocal configTimeTransactionManagerHolder = new ThreadLocal (); 86 87 private static final ThreadLocal configTimeLobHandlerHolder = new ThreadLocal (); 88 89 98 public static DataSource getConfigTimeDataSource() { 99 return (DataSource ) configTimeDataSourceHolder.get(); 100 } 101 102 111 public static TransactionManager getConfigTimeTransactionManager() { 112 return (TransactionManager ) configTimeTransactionManagerHolder.get(); 113 } 114 115 126 public static LobHandler getConfigTimeLobHandler() { 127 return (LobHandler) configTimeLobHandlerHolder.get(); 128 } 129 130 131 protected final Log logger = LogFactory.getLog(getClass()); 132 133 private Resource configLocation; 134 135 private Resource[] mappingLocations; 136 137 private Resource[] mappingJarLocations; 138 139 private Resource[] mappingDirectoryLocations; 140 141 private Properties hibernateProperties; 142 143 private DataSource dataSource; 144 145 private boolean useTransactionAwareDataSource = false; 146 147 private TransactionManager jtaTransactionManager; 148 149 private LobHandler lobHandler; 150 151 private Interceptor entityInterceptor; 152 153 private NamingStrategy namingStrategy; 154 155 private boolean schemaUpdate = false; 156 157 private Configuration configuration; 158 159 private SessionFactory sessionFactory; 160 161 162 169 public void setConfigLocation(Resource configLocation) { 170 this.configLocation = configLocation; 171 } 172 173 183 public void setMappingResources(String [] mappingResources) { 184 this.mappingLocations = new Resource[mappingResources.length]; 185 for (int i = 0; i < mappingResources.length; i++) { 186 this.mappingLocations[i] = new ClassPathResource(mappingResources[i].trim()); 187 } 188 } 189 190 199 public void setMappingLocations(Resource[] mappingLocations) { 200 this.mappingLocations = mappingLocations; 201 } 202 203 210 public void setMappingJarLocations(Resource[] mappingJarLocations) { 211 this.mappingJarLocations = mappingJarLocations; 212 } 213 214 221 public void setMappingDirectoryLocations(Resource[] mappingDirectoryLocations) { 222 this.mappingDirectoryLocations = mappingDirectoryLocations; 223 } 224 225 234 public void setHibernateProperties(Properties hibernateProperties) { 235 this.hibernateProperties = hibernateProperties; 236 } 237 238 242 public Properties getHibernateProperties() { 243 if (this.hibernateProperties == null) { 244 this.hibernateProperties = new Properties (); 245 } 246 return this.hibernateProperties; 247 } 248 249 270 public void setDataSource(DataSource dataSource) { 271 this.dataSource = dataSource; 272 } 273 274 310 public void setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource) { 311 this.useTransactionAwareDataSource = useTransactionAwareDataSource; 312 } 313 314 323 public void setJtaTransactionManager(TransactionManager jtaTransactionManager) { 324 this.jtaTransactionManager = jtaTransactionManager; 325 } 326 327 336 public void setLobHandler(LobHandler lobHandler) { 337 this.lobHandler = lobHandler; 338 } 339 340 354 public void setEntityInterceptor(Interceptor entityInterceptor) { 355 this.entityInterceptor = entityInterceptor; 356 } 357 358 363 public void setNamingStrategy(NamingStrategy namingStrategy) { 364 this.namingStrategy = namingStrategy; 365 } 366 367 375 public void setSchemaUpdate(boolean schemaUpdate) { 376 this.schemaUpdate = schemaUpdate; 377 } 378 379 380 385 public void afterPropertiesSet() throws IllegalArgumentException , HibernateException, IOException { 386 Configuration config = newConfiguration(); 388 389 if (this.dataSource != null) { 390 configTimeDataSourceHolder.set(this.dataSource); 392 } 393 394 if (this.jtaTransactionManager != null) { 395 configTimeTransactionManagerHolder.set(this.jtaTransactionManager); 397 } 398 399 if (this.lobHandler != null) { 400 configTimeLobHandlerHolder.set(this.lobHandler); 403 } 404 405 try { 406 407 if (this.entityInterceptor != null) { 408 config.setInterceptor(this.entityInterceptor); 410 } 411 412 if (this.namingStrategy != null) { 413 config.setNamingStrategy(this.namingStrategy); 415 } 416 417 if (this.configLocation != null) { 418 config.configure(this.configLocation.getURL()); 420 } 421 422 if (this.hibernateProperties != null) { 423 config.addProperties(this.hibernateProperties); 425 } 426 427 if (this.dataSource != null) { 428 config.setProperty(Environment.CONNECTION_PROVIDER, 430 this.useTransactionAwareDataSource ? 431 TransactionAwareDataSourceConnectionProvider.class.getName() : 432 LocalDataSourceConnectionProvider.class.getName()); 433 } 434 435 if (this.jtaTransactionManager != null) { 436 config.setProperty(Environment.TRANSACTION_MANAGER_STRATEGY, LocalTransactionManagerLookup.class.getName()); 438 } 439 440 if (this.mappingLocations != null) { 441 for (int i = 0; i < this.mappingLocations.length; i++) { 443 config.addInputStream(this.mappingLocations[i].getInputStream()); 444 } 445 } 446 447 if (this.mappingJarLocations != null) { 448 for (int i = 0; i < this.mappingJarLocations.length; i++) { 450 Resource resource = this.mappingJarLocations[i]; 451 config.addJar(resource.getFile()); 452 } 453 } 454 455 if (this.mappingDirectoryLocations != null) { 456 for (int i = 0; i < this.mappingDirectoryLocations.length; i++) { 458 File file = this.mappingDirectoryLocations[i].getFile(); 459 if (!file.isDirectory()) { 460 throw new IllegalArgumentException ( 461 "Mapping directory location [" + this.mappingDirectoryLocations[i] + 462 "] does not denote a directory"); 463 } 464 config.addDirectory(file); 465 } 466 } 467 468 postProcessConfiguration(config); 470 471 logger.info("Building new Hibernate SessionFactory"); 473 this.configuration = config; 474 this.sessionFactory = newSessionFactory(config); 475 } 476 477 finally { 478 if (this.dataSource != null) { 479 configTimeDataSourceHolder.set(null); 481 } 482 483 if (this.jtaTransactionManager != null) { 484 configTimeTransactionManagerHolder.set(null); 486 } 487 488 if (this.lobHandler != null) { 489 configTimeLobHandlerHolder.set(null); 491 } 492 } 493 494 if (this.schemaUpdate) { 496 updateDatabaseSchema(); 497 } 498 } 499 500 501 513 protected Configuration newConfiguration() throws HibernateException { 514 return new Configuration(); 515 } 516 517 524 protected void postProcessConfiguration(Configuration config) throws HibernateException { 525 } 526 527 539 protected SessionFactory newSessionFactory(Configuration config) throws HibernateException { 540 return config.buildSessionFactory(); 541 } 542 543 544 557 public void dropDatabaseSchema() throws DataAccessException { 558 logger.info("Dropping database schema for Hibernate SessionFactory"); 559 HibernateTemplate hibernateTemplate = new HibernateTemplate(this.sessionFactory); 560 hibernateTemplate.execute( 561 new HibernateCallback() { 562 public Object doInHibernate(Session session) throws HibernateException, SQLException { 563 Connection con = session.connection(); 564 Dialect dialect = Dialect.getDialect(configuration.getProperties()); 565 String [] sql = configuration.generateDropSchemaScript(dialect); 566 executeSchemaScript(con, sql); 567 return null; 568 } 569 } 570 ); 571 } 572 573 586 public void createDatabaseSchema() throws DataAccessException { 587 logger.info("Creating database schema for Hibernate SessionFactory"); 588 HibernateTemplate hibernateTemplate = new HibernateTemplate(this.sessionFactory); 589 hibernateTemplate.execute( 590 new HibernateCallback() { 591 public Object doInHibernate(Session session) throws HibernateException, SQLException { 592 Connection con = session.connection(); 593 Dialect dialect = Dialect.getDialect(configuration.getProperties()); 594 String [] sql = configuration.generateSchemaCreationScript(dialect); 595 executeSchemaScript(con, sql); 596 return null; 597 } 598 } 599 ); 600 } 601 602 617 public void updateDatabaseSchema() throws DataAccessException { 618 logger.info("Updating database schema for Hibernate SessionFactory"); 619 HibernateTemplate hibernateTemplate = new HibernateTemplate(this.sessionFactory); 620 hibernateTemplate.setFlushMode(HibernateTemplate.FLUSH_NEVER); 621 hibernateTemplate.execute( 622 new HibernateCallback() { 623 public Object doInHibernate(Session session) throws HibernateException, SQLException { 624 Connection con = session.connection(); 625 Dialect dialect = Dialect.getDialect(configuration.getProperties()); 626 DatabaseMetadata metadata = new DatabaseMetadata(con, dialect); 627 String [] sql = configuration.generateSchemaUpdateScript(dialect, metadata); 628 executeSchemaScript(con, sql); 629 return null; 630 } 631 } 632 ); 633 } 634 635 645 protected void executeSchemaScript(Connection con, String [] sql) throws SQLException { 646 if (sql != null && sql.length > 0) { 647 boolean oldAutoCommit = con.getAutoCommit(); 648 if (!oldAutoCommit) { 649 con.setAutoCommit(true); 650 } 651 try { 652 Statement stmt = con.createStatement(); 653 try { 654 for (int i = 0; i < sql.length; i++) { 655 executeSchemaStatement(stmt, sql[i]); 656 } 657 } 658 finally { 659 JdbcUtils.closeStatement(stmt); 660 } 661 } 662 finally { 663 if (!oldAutoCommit) { 664 con.setAutoCommit(false); 665 } 666 } 667 } 668 } 669 670 678 protected void executeSchemaStatement(Statement stmt, String sql) throws SQLException { 679 if (logger.isDebugEnabled()) { 680 logger.debug("Executing schema statement: " + sql); 681 } 682 try { 683 stmt.executeUpdate(sql); 684 } 685 catch (SQLException ex) { 686 if (logger.isWarnEnabled()) { 687 logger.warn("Unsuccessful schema statement: " + sql, ex); 688 } 689 } 690 } 691 692 693 697 public Configuration getConfiguration() { 698 return configuration; 699 } 700 701 702 705 public Object getObject() { 706 return this.sessionFactory; 707 } 708 709 public Class getObjectType() { 710 return (this.sessionFactory != null) ? this.sessionFactory.getClass() : SessionFactory.class; 711 } 712 713 public boolean isSingleton() { 714 return true; 715 } 716 717 718 721 public void destroy() throws HibernateException { 722 logger.info("Closing Hibernate SessionFactory"); 723 if (this.dataSource != null) { 724 configTimeDataSourceHolder.set(this.dataSource); 727 } 728 try { 729 this.sessionFactory.close(); 730 } 731 finally { 732 if (this.dataSource != null) { 733 configTimeDataSourceHolder.set(null); 735 } 736 } 737 } 738 739 } 740 | Popular Tags |