Source Code Cross Referenced for LocalSessionFactoryBean.java in  » J2EE » spring-framework-2.0.6 » org » springframework » orm » hibernate3 » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » spring framework 2.0.6 » org.springframework.orm.hibernate3 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2002-2007 the original author or authors.
0003:         *
0004:         * Licensed under the Apache License, Version 2.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         *
0008:         *      http://www.apache.org/licenses/LICENSE-2.0
0009:         *
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:
0017:        package org.springframework.orm.hibernate3;
0018:
0019:        import java.io.File;
0020:        import java.lang.reflect.Array;
0021:        import java.sql.Connection;
0022:        import java.sql.SQLException;
0023:        import java.sql.Statement;
0024:        import java.util.Collection;
0025:        import java.util.Enumeration;
0026:        import java.util.Iterator;
0027:        import java.util.Map;
0028:        import java.util.Properties;
0029:
0030:        import javax.sql.DataSource;
0031:        import javax.transaction.TransactionManager;
0032:
0033:        import org.hibernate.ConnectionReleaseMode;
0034:        import org.hibernate.HibernateException;
0035:        import org.hibernate.Interceptor;
0036:        import org.hibernate.Session;
0037:        import org.hibernate.SessionFactory;
0038:        import org.hibernate.cfg.Configuration;
0039:        import org.hibernate.cfg.Environment;
0040:        import org.hibernate.cfg.Mappings;
0041:        import org.hibernate.cfg.NamingStrategy;
0042:        import org.hibernate.dialect.Dialect;
0043:        import org.hibernate.engine.FilterDefinition;
0044:        import org.hibernate.event.EventListeners;
0045:        import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
0046:        import org.hibernate.transaction.JTATransactionFactory;
0047:
0048:        import org.springframework.beans.BeanUtils;
0049:        import org.springframework.core.io.ClassPathResource;
0050:        import org.springframework.core.io.Resource;
0051:        import org.springframework.dao.DataAccessException;
0052:        import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
0053:        import org.springframework.jdbc.support.JdbcUtils;
0054:        import org.springframework.jdbc.support.lob.LobHandler;
0055:        import org.springframework.util.Assert;
0056:        import org.springframework.util.StringUtils;
0057:
0058:        /**
0059:         * {@link org.springframework.beans.factory.FactoryBean} that creates a
0060:         * Hibernate {@link org.hibernate.SessionFactory}. This is the usual way to
0061:         * set up a shared Hibernate SessionFactory in a Spring application context;
0062:         * the SessionFactory can then be passed to Hibernate-based DAOs via
0063:         * dependency injection.
0064:         *
0065:         * <p>Configuration settings can either be read from a Hibernate XML file,
0066:         * specified as "configLocation", or completely via this class. A typical
0067:         * local configuration consists of one or more "mappingResources", various
0068:         * "hibernateProperties" (not strictly necessary), and a "dataSource" that the
0069:         * SessionFactory should use. The latter can also be specified via Hibernate
0070:         * properties, but "dataSource" supports any Spring-configured DataSource,
0071:         * instead of relying on Hibernate's own connection providers.
0072:         *
0073:         * <p>This SessionFactory handling strategy is appropriate for most types of
0074:         * applications, from Hibernate-only single database apps to ones that need
0075:         * distributed transactions. Either {@link HibernateTransactionManager} or
0076:         * {@link org.springframework.transaction.jta.JtaTransactionManager} can be
0077:         * used for transaction demarcation, with the latter only necessary for
0078:         * transactions which span multiple databases.
0079:         *
0080:         * <p>This factory bean will by default expose a transaction-aware SessionFactory
0081:         * proxy, letting data access code work with the plain Hibernate SessionFactory
0082:         * and its <code>getCurrentSession()</code> method, while still being able to
0083:         * participate in current Spring-managed transactions: with any transaction
0084:         * management strategy, either local or JTA / EJB CMT, and any transaction
0085:         * synchronization mechanism, either Spring or JTA. Furthermore,
0086:         * <code>getCurrentSession()</code> will also seamlessly work with
0087:         * a request-scoped Session managed by
0088:         * {@link org.springframework.orm.hibernate3.support.OpenSessionInViewFilter} /
0089:         * {@link org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor}.
0090:         *
0091:         * <p>Requires Hibernate 3.0.3 or later. Note that this factory will use
0092:         * "on_close" as default Hibernate connection release mode, unless in the
0093:         * case of a "jtaTransactionManager" specified, for the reason that
0094:         * this is appropriate for most Spring-based applications (in particular when
0095:         * using Spring's HibernateTransactionManager). Hibernate 3.0 used "on_close"
0096:         * as its own default too; however, Hibernate 3.1 changed this to "auto"
0097:         * (i.e. "after_statement" or "after_transaction").
0098:         *
0099:         * @author Juergen Hoeller
0100:         * @since 1.2
0101:         * @see HibernateTemplate#setSessionFactory
0102:         * @see HibernateTransactionManager#setSessionFactory
0103:         * @see #setExposeTransactionAwareSessionFactory
0104:         * @see #setJtaTransactionManager
0105:         * @see org.hibernate.SessionFactory#getCurrentSession()
0106:         * @see HibernateTransactionManager
0107:         */
0108:        public class LocalSessionFactoryBean extends AbstractSessionFactoryBean {
0109:
0110:            private static final ThreadLocal configTimeDataSourceHolder = new ThreadLocal();
0111:
0112:            private static final ThreadLocal configTimeTransactionManagerHolder = new ThreadLocal();
0113:
0114:            private static final ThreadLocal configTimeLobHandlerHolder = new ThreadLocal();
0115:
0116:            /**
0117:             * Return the DataSource for the currently configured Hibernate SessionFactory,
0118:             * to be used by LocalDataSourceConnectionProvoder.
0119:             * <p>This instance will be set before initialization of the corresponding
0120:             * SessionFactory, and reset immediately afterwards. It is thus only available
0121:             * during configuration.
0122:             * @see #setDataSource
0123:             * @see LocalDataSourceConnectionProvider
0124:             */
0125:            public static DataSource getConfigTimeDataSource() {
0126:                return (DataSource) configTimeDataSourceHolder.get();
0127:            }
0128:
0129:            /**
0130:             * Return the JTA TransactionManager for the currently configured Hibernate
0131:             * SessionFactory, to be used by LocalTransactionManagerLookup.
0132:             * <p>This instance will be set before initialization of the corresponding
0133:             * SessionFactory, and reset immediately afterwards. It is thus only available
0134:             * during configuration.
0135:             * @see #setJtaTransactionManager
0136:             * @see LocalTransactionManagerLookup
0137:             */
0138:            public static TransactionManager getConfigTimeTransactionManager() {
0139:                return (TransactionManager) configTimeTransactionManagerHolder
0140:                        .get();
0141:            }
0142:
0143:            /**
0144:             * Return the LobHandler for the currently configured Hibernate SessionFactory,
0145:             * to be used by UserType implementations like ClobStringType.
0146:             * <p>This instance will be set before initialization of the corresponding
0147:             * SessionFactory, and reset immediately afterwards. It is thus only available
0148:             * during configuration.
0149:             * @see #setLobHandler
0150:             * @see org.springframework.orm.hibernate3.support.ClobStringType
0151:             * @see org.springframework.orm.hibernate3.support.BlobByteArrayType
0152:             * @see org.springframework.orm.hibernate3.support.BlobSerializableType
0153:             */
0154:            public static LobHandler getConfigTimeLobHandler() {
0155:                return (LobHandler) configTimeLobHandlerHolder.get();
0156:            }
0157:
0158:            private Class configurationClass = Configuration.class;
0159:
0160:            private Resource[] configLocations;
0161:
0162:            private Resource[] mappingLocations;
0163:
0164:            private Resource[] cacheableMappingLocations;
0165:
0166:            private Resource[] mappingJarLocations;
0167:
0168:            private Resource[] mappingDirectoryLocations;
0169:
0170:            private Properties hibernateProperties;
0171:
0172:            private DataSource dataSource;
0173:
0174:            private boolean useTransactionAwareDataSource = false;
0175:
0176:            private TransactionManager jtaTransactionManager;
0177:
0178:            private LobHandler lobHandler;
0179:
0180:            private Interceptor entityInterceptor;
0181:
0182:            private NamingStrategy namingStrategy;
0183:
0184:            private TypeDefinitionBean[] typeDefinitions;
0185:
0186:            private FilterDefinition[] filterDefinitions;
0187:
0188:            private Properties entityCacheStrategies;
0189:
0190:            private Properties collectionCacheStrategies;
0191:
0192:            private Map eventListeners;
0193:
0194:            private boolean schemaUpdate = false;
0195:
0196:            private Configuration configuration;
0197:
0198:            /**
0199:             * Specify the Hibernate Configuration class to use.
0200:             * Default is "org.hibernate.cfg.Configuration"; any subclass of
0201:             * this default Hibernate Configuration class can be specified.
0202:             * <p>Can be set to "org.hibernate.cfg.AnnotationConfiguration" for
0203:             * using Hibernate3 annotation support (initially only available as
0204:             * alpha download separate from the main Hibernate3 distribution).
0205:             * <p>Annotated packages and annotated classes can be specified via the
0206:             * corresponding tags in "hibernate.cfg.xml" then, so this will usually
0207:             * be combined with a "configLocation" property that points at such a
0208:             * standard Hibernate configuration file.
0209:             * @see #setConfigLocation
0210:             * @see org.hibernate.cfg.Configuration
0211:             * @see org.hibernate.cfg.AnnotationConfiguration
0212:             */
0213:            public void setConfigurationClass(Class configurationClass) {
0214:                if (configurationClass == null
0215:                        || !Configuration.class
0216:                                .isAssignableFrom(configurationClass)) {
0217:                    throw new IllegalArgumentException(
0218:                            "configurationClass must be assignable to [org.hibernate.cfg.Configuration]");
0219:                }
0220:                this .configurationClass = configurationClass;
0221:            }
0222:
0223:            /**
0224:             * Set the location of a single Hibernate XML config file, for example as
0225:             * classpath resource "classpath:hibernate.cfg.xml".
0226:             * <p>Note: Can be omitted when all necessary properties and mapping
0227:             * resources are specified locally via this bean.
0228:             * @see org.hibernate.cfg.Configuration#configure(java.net.URL)
0229:             */
0230:            public void setConfigLocation(Resource configLocation) {
0231:                this .configLocations = new Resource[] { configLocation };
0232:            }
0233:
0234:            /**
0235:             * Set the locations of multiple Hibernate XML config files, for example as
0236:             * classpath resources "classpath:hibernate.cfg.xml,classpath:extension.cfg.xml".
0237:             * <p>Note: Can be omitted when all necessary properties and mapping
0238:             * resources are specified locally via this bean.
0239:             * @see org.hibernate.cfg.Configuration#configure(java.net.URL)
0240:             */
0241:            public void setConfigLocations(Resource[] configLocations) {
0242:                this .configLocations = configLocations;
0243:            }
0244:
0245:            /**
0246:             * Set Hibernate mapping resources to be found in the class path,
0247:             * like "example.hbm.xml" or "mypackage/example.hbm.xml".
0248:             * Analogous to mapping entries in a Hibernate XML config file.
0249:             * Alternative to the more generic setMappingLocations method.
0250:             * <p>Can be used to add to mappings from a Hibernate XML config file,
0251:             * or to specify all mappings locally.
0252:             * @see #setMappingLocations
0253:             * @see org.hibernate.cfg.Configuration#addResource
0254:             */
0255:            public void setMappingResources(String[] mappingResources) {
0256:                this .mappingLocations = new Resource[mappingResources.length];
0257:                for (int i = 0; i < mappingResources.length; i++) {
0258:                    this .mappingLocations[i] = new ClassPathResource(
0259:                            mappingResources[i].trim());
0260:                }
0261:            }
0262:
0263:            /**
0264:             * Set locations of Hibernate mapping files, for example as classpath
0265:             * resource "classpath:example.hbm.xml". Supports any resource location
0266:             * via Spring's resource abstraction, for example relative paths like
0267:             * "WEB-INF/mappings/example.hbm.xml" when running in an application context.
0268:             * <p>Can be used to add to mappings from a Hibernate XML config file,
0269:             * or to specify all mappings locally.
0270:             * @see org.hibernate.cfg.Configuration#addInputStream
0271:             */
0272:            public void setMappingLocations(Resource[] mappingLocations) {
0273:                this .mappingLocations = mappingLocations;
0274:            }
0275:
0276:            /**
0277:             * Set locations of cacheable Hibernate mapping files, for example as web app
0278:             * resource "/WEB-INF/mapping/example.hbm.xml". Supports any resource location
0279:             * via Spring's resource abstraction, as long as the resource can be resolved
0280:             * in the file system.
0281:             * <p>Can be used to add to mappings from a Hibernate XML config file,
0282:             * or to specify all mappings locally.
0283:             * @see org.hibernate.cfg.Configuration#addCacheableFile(java.io.File)
0284:             */
0285:            public void setCacheableMappingLocations(
0286:                    Resource[] cacheableMappingLocations) {
0287:                this .cacheableMappingLocations = cacheableMappingLocations;
0288:            }
0289:
0290:            /**
0291:             * Set locations of jar files that contain Hibernate mapping resources,
0292:             * like "WEB-INF/lib/example.hbm.jar".
0293:             * <p>Can be used to add to mappings from a Hibernate XML config file,
0294:             * or to specify all mappings locally.
0295:             * @see org.hibernate.cfg.Configuration#addJar(java.io.File)
0296:             */
0297:            public void setMappingJarLocations(Resource[] mappingJarLocations) {
0298:                this .mappingJarLocations = mappingJarLocations;
0299:            }
0300:
0301:            /**
0302:             * Set locations of directories that contain Hibernate mapping resources,
0303:             * like "WEB-INF/mappings".
0304:             * <p>Can be used to add to mappings from a Hibernate XML config file,
0305:             * or to specify all mappings locally.
0306:             * @see org.hibernate.cfg.Configuration#addDirectory(java.io.File)
0307:             */
0308:            public void setMappingDirectoryLocations(
0309:                    Resource[] mappingDirectoryLocations) {
0310:                this .mappingDirectoryLocations = mappingDirectoryLocations;
0311:            }
0312:
0313:            /**
0314:             * Set Hibernate properties, such as "hibernate.dialect".
0315:             * <p>Can be used to override values in a Hibernate XML config file,
0316:             * or to specify all necessary properties locally.
0317:             * <p>Note: Do not specify a transaction provider here when using
0318:             * Spring-driven transactions. It is also advisable to omit connection
0319:             * provider settings and use a Spring-set DataSource instead.
0320:             * @see #setDataSource
0321:             */
0322:            public void setHibernateProperties(Properties hibernateProperties) {
0323:                this .hibernateProperties = hibernateProperties;
0324:            }
0325:
0326:            /**
0327:             * Return the Hibernate properties, if any. Mainly available for
0328:             * configuration through property paths that specify individual keys.
0329:             */
0330:            public Properties getHibernateProperties() {
0331:                if (this .hibernateProperties == null) {
0332:                    this .hibernateProperties = new Properties();
0333:                }
0334:                return this .hibernateProperties;
0335:            }
0336:
0337:            /**
0338:             * Set the DataSource to be used by the SessionFactory.
0339:             * If set, this will override corresponding settings in Hibernate properties.
0340:             * <p>If this is set, the Hibernate settings should not define
0341:             * a connection provider to avoid meaningless double configuration.
0342:             * <p>If using HibernateTransactionManager as transaction strategy, consider
0343:             * proxying your target DataSource with a LazyConnectionDataSourceProxy.
0344:             * This defers fetching of an actual JDBC Connection until the first JDBC
0345:             * Statement gets executed, even within JDBC transactions (as performed by
0346:             * HibernateTransactionManager). Such lazy fetching is particularly beneficial
0347:             * for read-only operations, in particular if the chances of resolving the
0348:             * result in the second-level cache are high.
0349:             * <p>As JTA and transactional JNDI DataSources already provide lazy enlistment
0350:             * of JDBC Connections, LazyConnectionDataSourceProxy does not add value with
0351:             * JTA (i.e. Spring's JtaTransactionManager) as transaction strategy.
0352:             * @see #setUseTransactionAwareDataSource
0353:             * @see LocalDataSourceConnectionProvider
0354:             * @see HibernateTransactionManager
0355:             * @see org.springframework.transaction.jta.JtaTransactionManager
0356:             * @see org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy
0357:             */
0358:            public void setDataSource(DataSource dataSource) {
0359:                this .dataSource = dataSource;
0360:            }
0361:
0362:            /**
0363:             * Set whether to use a transaction-aware DataSource for the SessionFactory,
0364:             * i.e. whether to automatically wrap the passed-in DataSource with Spring's
0365:             * TransactionAwareDataSourceProxy.
0366:             * <p>Default is "false": LocalSessionFactoryBean is usually used with Spring's
0367:             * HibernateTransactionManager or JtaTransactionManager, both of which work nicely
0368:             * on a plain JDBC DataSource. Hibernate Sessions and their JDBC Connections are
0369:             * fully managed by the Hibernate/JTA transaction infrastructure in such a scenario.
0370:             * <p>If you switch this flag to "true", Spring's Hibernate access will be able to
0371:             * <i>participate in JDBC-based transactions managed outside of Hibernate</i>
0372:             * (for example, by Spring's DataSourceTransactionManager). This can be convenient
0373:             * if you need a different local transaction strategy for another O/R mapping tool,
0374:             * for example, but still want Hibernate access to join into those transactions.
0375:             * <p>A further benefit of this option is that <i>plain Sessions opened directly
0376:             * via the SessionFactory</i>, outside of Spring's Hibernate support, will still
0377:             * participate in active Spring-managed transactions. However, consider using
0378:             * Hibernate's <code>getCurrentSession()</code> method instead (see javadoc of
0379:             * "exposeTransactionAwareSessionFactory" property).
0380:             * <p>As a further effect, using a transaction-aware DataSource will <i>apply
0381:             * remaining transaction timeouts to all created JDBC Statements</i>. This means
0382:             * that all operations performed by the SessionFactory will automatically
0383:             * participate in Spring-managed transaction timeouts, not just queries.
0384:             * This adds value even for HibernateTransactionManager, but only on Hibernate 3.0,
0385:             * as there is a direct transaction timeout facility in Hibernate 3.1.
0386:             * <p><b>WARNING:</b> When using a transaction-aware JDBC DataSource in combination
0387:             * with OpenSessionInViewFilter/Interceptor, whether participating in JTA or
0388:             * external JDBC-based transactions, it is strongly recommended to set Hibernate's
0389:             * Connection release mode to "after_transaction" or "after_statement", which
0390:             * guarantees proper Connection handling in such a scenario. In contrast to that,
0391:             * HibernateTransactionManager generally requires release mode "on_close".
0392:             * <p>Note: If you want to use Hibernate's Connection release mode "after_statement"
0393:             * with a DataSource specified on this LocalSessionFactoryBean (for example, a
0394:             * JTA-aware DataSource fetched from JNDI), switch this setting to "true".
0395:             * Else, the ConnectionProvider used underneath will vote against aggressive
0396:             * release and thus silently switch to release mode "after_transaction".
0397:             * @see #setDataSource
0398:             * @see #setExposeTransactionAwareSessionFactory
0399:             * @see org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
0400:             * @see org.springframework.jdbc.datasource.DataSourceTransactionManager
0401:             * @see org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
0402:             * @see org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor
0403:             * @see HibernateTransactionManager
0404:             * @see org.springframework.transaction.jta.JtaTransactionManager
0405:             */
0406:            public void setUseTransactionAwareDataSource(
0407:                    boolean useTransactionAwareDataSource) {
0408:                this .useTransactionAwareDataSource = useTransactionAwareDataSource;
0409:            }
0410:
0411:            /**
0412:             * Set the JTA TransactionManager to be used for Hibernate's
0413:             * TransactionManagerLookup. If set, this will override corresponding
0414:             * settings in Hibernate properties. Allows to use a Spring-managed
0415:             * JTA TransactionManager for Hibernate's cache synchronization.
0416:             * <p>Note: If this is set, the Hibernate settings should not define a
0417:             * transaction manager lookup to avoid meaningless double configuration.
0418:             * @see LocalTransactionManagerLookup
0419:             */
0420:            public void setJtaTransactionManager(
0421:                    TransactionManager jtaTransactionManager) {
0422:                this .jtaTransactionManager = jtaTransactionManager;
0423:            }
0424:
0425:            /**
0426:             * Set the LobHandler to be used by the SessionFactory.
0427:             * Will be exposed at config time for UserType implementations.
0428:             * @see #getConfigTimeLobHandler
0429:             * @see org.hibernate.usertype.UserType
0430:             * @see org.springframework.orm.hibernate3.support.ClobStringType
0431:             * @see org.springframework.orm.hibernate3.support.BlobByteArrayType
0432:             * @see org.springframework.orm.hibernate3.support.BlobSerializableType
0433:             */
0434:            public void setLobHandler(LobHandler lobHandler) {
0435:                this .lobHandler = lobHandler;
0436:            }
0437:
0438:            /**
0439:             * Set a Hibernate entity interceptor that allows to inspect and change
0440:             * property values before writing to and reading from the database.
0441:             * Will get applied to any new Session created by this factory.
0442:             * <p>Such an interceptor can either be set at the SessionFactory level, i.e. on
0443:             * LocalSessionFactoryBean, or at the Session level, i.e. on HibernateTemplate,
0444:             * HibernateInterceptor, and HibernateTransactionManager. It's preferable to set
0445:             * it on LocalSessionFactoryBean or HibernateTransactionManager to avoid repeated
0446:             * configuration and guarantee consistent behavior in transactions.
0447:             * @see HibernateTemplate#setEntityInterceptor
0448:             * @see HibernateInterceptor#setEntityInterceptor
0449:             * @see HibernateTransactionManager#setEntityInterceptor
0450:             * @see org.hibernate.cfg.Configuration#setInterceptor
0451:             */
0452:            public void setEntityInterceptor(Interceptor entityInterceptor) {
0453:                this .entityInterceptor = entityInterceptor;
0454:            }
0455:
0456:            /**
0457:             * Set a Hibernate NamingStrategy for the SessionFactory, determining the
0458:             * physical column and table names given the info in the mapping document.
0459:             * @see org.hibernate.cfg.Configuration#setNamingStrategy
0460:             */
0461:            public void setNamingStrategy(NamingStrategy namingStrategy) {
0462:                this .namingStrategy = namingStrategy;
0463:            }
0464:
0465:            /**
0466:             * Specify the Hibernate type definitions to register with the SessionFactory,
0467:             * as Spring TypeDefinitionBean instances. This is an alternative to specifying
0468:             * <&lt;typedef&gt; elements in Hibernate mapping files.
0469:             * <p>Unfortunately, Hibernate itself does not define a complete object that
0470:             * represents a type definition, hence the need for Spring's TypeDefinitionBean.
0471:             * @see TypeDefinitionBean
0472:             * @see org.hibernate.cfg.Mappings#addTypeDef(String, String, java.util.Properties)
0473:             */
0474:            public void setTypeDefinitions(TypeDefinitionBean[] typeDefinitions) {
0475:                this .typeDefinitions = typeDefinitions;
0476:            }
0477:
0478:            /**
0479:             * Specify the Hibernate FilterDefinitions to register with the SessionFactory.
0480:             * This is an alternative to specifying <&lt;filter-def&gt; elements in
0481:             * Hibernate mapping files.
0482:             * <p>Typically, the passed-in FilterDefinition objects will have been defined
0483:             * as Spring FilterDefinitionFactoryBeans, probably as inner beans within the
0484:             * LocalSessionFactoryBean definition.
0485:             * @see FilterDefinitionFactoryBean
0486:             * @see org.hibernate.cfg.Configuration#addFilterDefinition
0487:             */
0488:            public void setFilterDefinitions(
0489:                    FilterDefinition[] filterDefinitions) {
0490:                this .filterDefinitions = filterDefinitions;
0491:            }
0492:
0493:            /**
0494:             * Specify the cache strategies for entities (persistent classes or named entities).
0495:             * This configuration setting corresponds to the &lt;class-cache&gt; entry
0496:             * in the "hibernate.cfg.xml" configuration format.
0497:             * <p>For example:
0498:             * <pre>
0499:             * &lt;property name="entityCacheStrategies"&gt;
0500:             *   &lt;props&gt;
0501:             *     &lt;prop key="com.mycompany.Customer"&gt;read-write&lt;/prop&gt;
0502:             *     &lt;prop key="com.mycompany.Product"&gt;read-only,myRegion&lt;/prop&gt;
0503:             *   &lt;/props&gt;
0504:             * &lt;/property&gt;</pre>
0505:             * Note that appending a cache region name (with a comma separator) is only
0506:             * supported on Hibernate 3.1, where this functionality is publically available.
0507:             * @param entityCacheStrategies properties that define entity cache strategies,
0508:             * with class names as keys and cache concurrency strategies as values
0509:             * @see org.hibernate.cfg.Configuration#setCacheConcurrencyStrategy(String, String)
0510:             */
0511:            public void setEntityCacheStrategies(
0512:                    Properties entityCacheStrategies) {
0513:                this .entityCacheStrategies = entityCacheStrategies;
0514:            }
0515:
0516:            /**
0517:             * Specify the cache strategies for persistent collections (with specific roles).
0518:             * This configuration setting corresponds to the &lt;collection-cache&gt; entry
0519:             * in the "hibernate.cfg.xml" configuration format.
0520:             * <p>For example:
0521:             * <pre>
0522:             * &lt;property name="collectionCacheStrategies"&gt;
0523:             *   &lt;props&gt;
0524:             *     &lt;prop key="com.mycompany.Order.items">read-write&lt;/prop&gt;
0525:             *     &lt;prop key="com.mycompany.Product.categories"&gt;read-only,myRegion&lt;/prop&gt;
0526:             *   &lt;/props&gt;
0527:             * &lt;/property&gt;</pre>
0528:             * Note that appending a cache region name (with a comma separator) is only
0529:             * supported on Hibernate 3.1, where this functionality is publically available.
0530:             * @param collectionCacheStrategies properties that define collection cache strategies,
0531:             * with collection roles as keys and cache concurrency strategies as values
0532:             * @see org.hibernate.cfg.Configuration#setCollectionCacheConcurrencyStrategy(String, String)
0533:             */
0534:            public void setCollectionCacheStrategies(
0535:                    Properties collectionCacheStrategies) {
0536:                this .collectionCacheStrategies = collectionCacheStrategies;
0537:            }
0538:
0539:            /**
0540:             * Specify the Hibernate event listeners to register, with listener types
0541:             * as keys and listener objects as values.
0542:             * <p>Instead of a single listener object, you can also pass in a list
0543:             * or set of listeners objects as value. However, this is only supported
0544:             * on Hibernate 3.1.
0545:             * <p>See the Hibernate documentation for further details on listener types
0546:             * and associated listener interfaces.
0547:             * @param eventListeners Map with listener type Strings as keys and
0548:             * listener objects as values
0549:             * @see org.hibernate.cfg.Configuration#setListener(String, Object)
0550:             */
0551:            public void setEventListeners(Map eventListeners) {
0552:                this .eventListeners = eventListeners;
0553:            }
0554:
0555:            /**
0556:             * Set whether to execute a schema update after SessionFactory initialization.
0557:             * <p>For details on how to make schema update scripts work, see the Hibernate
0558:             * documentation, as this class leverages the same schema update script support
0559:             * in org.hibernate.cfg.Configuration as Hibernate's own SchemaUpdate tool.
0560:             * @see org.hibernate.cfg.Configuration#generateSchemaUpdateScript
0561:             * @see org.hibernate.tool.hbm2ddl.SchemaUpdate
0562:             */
0563:            public void setSchemaUpdate(boolean schemaUpdate) {
0564:                this .schemaUpdate = schemaUpdate;
0565:            }
0566:
0567:            protected SessionFactory buildSessionFactory() throws Exception {
0568:                // Create Configuration instance.
0569:                Configuration config = newConfiguration();
0570:
0571:                if (this .dataSource != null) {
0572:                    // Make given DataSource available for SessionFactory configuration.
0573:                    configTimeDataSourceHolder.set(this .dataSource);
0574:                }
0575:
0576:                if (this .jtaTransactionManager != null) {
0577:                    // Make Spring-provided JTA TransactionManager available.
0578:                    configTimeTransactionManagerHolder
0579:                            .set(this .jtaTransactionManager);
0580:                }
0581:
0582:                if (this .lobHandler != null) {
0583:                    // Make given LobHandler available for SessionFactory configuration.
0584:                    // Do early because because mapping resource might refer to custom types.
0585:                    configTimeLobHandlerHolder.set(this .lobHandler);
0586:                }
0587:
0588:                try {
0589:                    if (this .jtaTransactionManager != null) {
0590:                        // Set Spring-provided JTA TransactionManager as Hibernate property.
0591:                        config.setProperty(
0592:                                Environment.TRANSACTION_MANAGER_STRATEGY,
0593:                                LocalTransactionManagerLookup.class.getName());
0594:                        config.setProperty(Environment.TRANSACTION_STRATEGY,
0595:                                JTATransactionFactory.class.getName());
0596:                    } else {
0597:                        // Set connection release mode "on_close" as default.
0598:                        // This was the case for Hibernate 3.0; Hibernate 3.1 changed
0599:                        // it to "auto" (i.e. "after_statement" or "after_transaction").
0600:                        // However, for Spring's resource management (in particular for
0601:                        // HibernateTransactionManager), "on_close" is the better default.
0602:                        config.setProperty(Environment.RELEASE_CONNECTIONS,
0603:                                ConnectionReleaseMode.ON_CLOSE.toString());
0604:                    }
0605:
0606:                    if (!isExposeTransactionAwareSessionFactory()) {
0607:                        // Not exposing a SessionFactory proxy with transaction-aware
0608:                        // getCurrentSession() method -> set Hibernate 3.1 CurrentSessionContext
0609:                        // implementation instead, providing the Spring-managed Session that way.
0610:                        // Can be overridden by a custom value for the corresponding Hibernate property.
0611:                        config
0612:                                .setProperty(
0613:                                        Environment.CURRENT_SESSION_CONTEXT_CLASS,
0614:                                        "org.springframework.orm.hibernate3.SpringSessionContext");
0615:                    }
0616:
0617:                    if (this .entityInterceptor != null) {
0618:                        // Set given entity interceptor at SessionFactory level.
0619:                        config.setInterceptor(this .entityInterceptor);
0620:                    }
0621:
0622:                    if (this .namingStrategy != null) {
0623:                        // Pass given naming strategy to Hibernate Configuration.
0624:                        config.setNamingStrategy(this .namingStrategy);
0625:                    }
0626:
0627:                    if (this .typeDefinitions != null) {
0628:                        // Register specified Hibernate type definitions.
0629:                        Mappings mappings = config.createMappings();
0630:                        for (int i = 0; i < this .typeDefinitions.length; i++) {
0631:                            TypeDefinitionBean typeDef = this .typeDefinitions[i];
0632:                            mappings.addTypeDef(typeDef.getTypeName(), typeDef
0633:                                    .getTypeClass(), typeDef.getParameters());
0634:                        }
0635:                    }
0636:
0637:                    if (this .filterDefinitions != null) {
0638:                        // Register specified Hibernate FilterDefinitions.
0639:                        for (int i = 0; i < this .filterDefinitions.length; i++) {
0640:                            config
0641:                                    .addFilterDefinition(this .filterDefinitions[i]);
0642:                        }
0643:                    }
0644:
0645:                    if (this .configLocations != null) {
0646:                        for (int i = 0; i < this .configLocations.length; i++) {
0647:                            // Load Hibernate configuration from given location.
0648:                            config.configure(this .configLocations[i].getURL());
0649:                        }
0650:                    }
0651:
0652:                    if (this .hibernateProperties != null) {
0653:                        // Add given Hibernate properties to Configuration.
0654:                        config.addProperties(this .hibernateProperties);
0655:                    }
0656:
0657:                    if (this .dataSource != null) {
0658:                        boolean actuallyTransactionAware = (this .useTransactionAwareDataSource || this .dataSource instanceof  TransactionAwareDataSourceProxy);
0659:                        // Set Spring-provided DataSource as Hibernate ConnectionProvider.
0660:                        config
0661:                                .setProperty(
0662:                                        Environment.CONNECTION_PROVIDER,
0663:                                        actuallyTransactionAware ? TransactionAwareDataSourceConnectionProvider.class
0664:                                                .getName()
0665:                                                : LocalDataSourceConnectionProvider.class
0666:                                                        .getName());
0667:                    }
0668:
0669:                    if (this .mappingLocations != null) {
0670:                        // Register given Hibernate mapping definitions, contained in resource files.
0671:                        for (int i = 0; i < this .mappingLocations.length; i++) {
0672:                            config.addInputStream(this .mappingLocations[i]
0673:                                    .getInputStream());
0674:                        }
0675:                    }
0676:
0677:                    if (this .cacheableMappingLocations != null) {
0678:                        // Register given cacheable Hibernate mapping definitions, read from the file system.
0679:                        for (int i = 0; i < this .cacheableMappingLocations.length; i++) {
0680:                            config
0681:                                    .addCacheableFile(this .cacheableMappingLocations[i]
0682:                                            .getFile());
0683:                        }
0684:                    }
0685:
0686:                    if (this .mappingJarLocations != null) {
0687:                        // Register given Hibernate mapping definitions, contained in jar files.
0688:                        for (int i = 0; i < this .mappingJarLocations.length; i++) {
0689:                            Resource resource = this .mappingJarLocations[i];
0690:                            config.addJar(resource.getFile());
0691:                        }
0692:                    }
0693:
0694:                    if (this .mappingDirectoryLocations != null) {
0695:                        // Register all Hibernate mapping definitions in the given directories.
0696:                        for (int i = 0; i < this .mappingDirectoryLocations.length; i++) {
0697:                            File file = this .mappingDirectoryLocations[i]
0698:                                    .getFile();
0699:                            if (!file.isDirectory()) {
0700:                                throw new IllegalArgumentException(
0701:                                        "Mapping directory location ["
0702:                                                + this .mappingDirectoryLocations[i]
0703:                                                + "] does not denote a directory");
0704:                            }
0705:                            config.addDirectory(file);
0706:                        }
0707:                    }
0708:
0709:                    if (this .entityCacheStrategies != null) {
0710:                        // Register cache strategies for mapped entities.
0711:                        for (Enumeration classNames = this .entityCacheStrategies
0712:                                .propertyNames(); classNames.hasMoreElements();) {
0713:                            String className = (String) classNames
0714:                                    .nextElement();
0715:                            String[] strategyAndRegion = StringUtils
0716:                                    .commaDelimitedListToStringArray(this .entityCacheStrategies
0717:                                            .getProperty(className));
0718:                            if (strategyAndRegion.length > 1) {
0719:                                config.setCacheConcurrencyStrategy(className,
0720:                                        strategyAndRegion[0],
0721:                                        strategyAndRegion[1]);
0722:                            } else if (strategyAndRegion.length > 0) {
0723:                                config.setCacheConcurrencyStrategy(className,
0724:                                        strategyAndRegion[0]);
0725:                            }
0726:                        }
0727:                    }
0728:
0729:                    if (this .collectionCacheStrategies != null) {
0730:                        // Register cache strategies for mapped collections.
0731:                        for (Enumeration collRoles = this .collectionCacheStrategies
0732:                                .propertyNames(); collRoles.hasMoreElements();) {
0733:                            String collRole = (String) collRoles.nextElement();
0734:                            String[] strategyAndRegion = StringUtils
0735:                                    .commaDelimitedListToStringArray(this .collectionCacheStrategies
0736:                                            .getProperty(collRole));
0737:                            if (strategyAndRegion.length > 1) {
0738:                                config.setCollectionCacheConcurrencyStrategy(
0739:                                        collRole, strategyAndRegion[0],
0740:                                        strategyAndRegion[1]);
0741:                            } else if (strategyAndRegion.length > 0) {
0742:                                config.setCollectionCacheConcurrencyStrategy(
0743:                                        collRole, strategyAndRegion[0]);
0744:                            }
0745:                        }
0746:                    }
0747:
0748:                    if (this .eventListeners != null) {
0749:                        // Register specified Hibernate event listeners.
0750:                        for (Iterator it = this .eventListeners.entrySet()
0751:                                .iterator(); it.hasNext();) {
0752:                            Map.Entry entry = (Map.Entry) it.next();
0753:                            Assert
0754:                                    .isTrue(entry.getKey() instanceof  String,
0755:                                            "Event listener key needs to be of type String");
0756:                            String listenerType = (String) entry.getKey();
0757:                            Object listenerObject = entry.getValue();
0758:                            if (listenerObject instanceof  Collection) {
0759:                                Collection listeners = (Collection) listenerObject;
0760:                                EventListeners listenerRegistry = config
0761:                                        .getEventListeners();
0762:                                Object[] listenerArray = (Object[]) Array
0763:                                        .newInstance(
0764:                                                listenerRegistry
0765:                                                        .getListenerClassFor(listenerType),
0766:                                                listeners.size());
0767:                                listenerArray = listeners
0768:                                        .toArray(listenerArray);
0769:                                config
0770:                                        .setListeners(listenerType,
0771:                                                listenerArray);
0772:                            } else {
0773:                                config
0774:                                        .setListener(listenerType,
0775:                                                listenerObject);
0776:                            }
0777:                        }
0778:                    }
0779:
0780:                    // Perform custom post-processing in subclasses.
0781:                    postProcessConfiguration(config);
0782:
0783:                    // Build SessionFactory instance.
0784:                    logger.info("Building new Hibernate SessionFactory");
0785:                    this .configuration = config;
0786:                    return newSessionFactory(config);
0787:                }
0788:
0789:                finally {
0790:                    if (this .dataSource != null) {
0791:                        // Reset DataSource holder.
0792:                        configTimeDataSourceHolder.set(null);
0793:                    }
0794:
0795:                    if (this .jtaTransactionManager != null) {
0796:                        // Reset TransactionManager holder.
0797:                        configTimeTransactionManagerHolder.set(null);
0798:                    }
0799:
0800:                    if (this .lobHandler != null) {
0801:                        // Reset LobHandler holder.
0802:                        configTimeLobHandlerHolder.set(null);
0803:                    }
0804:                }
0805:            }
0806:
0807:            /**
0808:             * Subclasses can override this method to perform custom initialization
0809:             * of the Configuration instance used for SessionFactory creation.
0810:             * The properties of this LocalSessionFactoryBean will be applied to
0811:             * the Configuration object that gets returned here.
0812:             * <p>The default implementation creates a new Configuration instance.
0813:             * A custom implementation could prepare the instance in a specific way,
0814:             * or use a custom Configuration subclass.
0815:             * @return the Configuration instance
0816:             * @throws HibernateException in case of Hibernate initialization errors
0817:             * @see org.hibernate.cfg.Configuration#Configuration()
0818:             */
0819:            protected Configuration newConfiguration()
0820:                    throws HibernateException {
0821:                return (Configuration) BeanUtils
0822:                        .instantiateClass(this .configurationClass);
0823:            }
0824:
0825:            /**
0826:             * To be implemented by subclasses that want to to perform custom
0827:             * post-processing of the Configuration object after this FactoryBean
0828:             * performed its default initialization.
0829:             * @param config the current Configuration object
0830:             * @throws HibernateException in case of Hibernate initialization errors
0831:             */
0832:            protected void postProcessConfiguration(Configuration config)
0833:                    throws HibernateException {
0834:            }
0835:
0836:            /**
0837:             * Subclasses can override this method to perform custom initialization
0838:             * of the SessionFactory instance, creating it via the given Configuration
0839:             * object that got prepared by this LocalSessionFactoryBean.
0840:             * <p>The default implementation invokes Configuration's buildSessionFactory.
0841:             * A custom implementation could prepare the instance in a specific way,
0842:             * or use a custom SessionFactoryImpl subclass.
0843:             * @param config Configuration prepared by this LocalSessionFactoryBean
0844:             * @return the SessionFactory instance
0845:             * @throws HibernateException in case of Hibernate initialization errors
0846:             * @see org.hibernate.cfg.Configuration#buildSessionFactory
0847:             */
0848:            protected SessionFactory newSessionFactory(Configuration config)
0849:                    throws HibernateException {
0850:                return config.buildSessionFactory();
0851:            }
0852:
0853:            /**
0854:             * Return the Configuration object used to build the SessionFactory.
0855:             * Allows access to configuration metadata stored there (rarely needed).
0856:             * @throws IllegalStateException if the Configuration object has not been initialized yet
0857:             */
0858:            public final Configuration getConfiguration() {
0859:                if (this .configuration == null) {
0860:                    throw new IllegalStateException(
0861:                            "Configuration not initialized yet");
0862:                }
0863:                return this .configuration;
0864:            }
0865:
0866:            /**
0867:             * Executes schema update if requested.
0868:             * @see #setSchemaUpdate
0869:             * @see #updateDatabaseSchema()
0870:             */
0871:            protected void afterSessionFactoryCreation() throws Exception {
0872:                if (this .schemaUpdate) {
0873:                    if (this .dataSource != null) {
0874:                        // Make given DataSource available for the schema update,
0875:                        // which unfortunately reinstantiates a ConnectionProvider.
0876:                        configTimeDataSourceHolder.set(this .dataSource);
0877:                    }
0878:                    try {
0879:                        updateDatabaseSchema();
0880:                    } finally {
0881:                        if (this .dataSource != null) {
0882:                            // Reset DataSource holder.
0883:                            configTimeDataSourceHolder.set(null);
0884:                        }
0885:                    }
0886:                }
0887:            }
0888:
0889:            /**
0890:             * Allows for schema export on shutdown.
0891:             */
0892:            public void destroy() throws HibernateException {
0893:                if (this .dataSource != null) {
0894:                    // Make given DataSource available for potential SchemaExport,
0895:                    // which unfortunately reinstantiates a ConnectionProvider.
0896:                    configTimeDataSourceHolder.set(this .dataSource);
0897:                }
0898:                try {
0899:                    super .destroy();
0900:                } finally {
0901:                    if (this .dataSource != null) {
0902:                        // Reset DataSource holder.
0903:                        configTimeDataSourceHolder.set(null);
0904:                    }
0905:                }
0906:            }
0907:
0908:            /**
0909:             * Execute schema drop script, determined by the Configuration object
0910:             * used for creating the SessionFactory. A replacement for Hibernate's
0911:             * SchemaExport class, to be invoked on application setup.
0912:             * <p>Fetch the LocalSessionFactoryBean itself rather than the exposed
0913:             * SessionFactory to be able to invoke this method, e.g. via
0914:             * <code>LocalSessionFactoryBean lsfb = (LocalSessionFactoryBean) ctx.getBean("&mySessionFactory");</code>.
0915:             * <p>Uses the SessionFactory that this bean generates for accessing a JDBC
0916:             * connection to perform the script.
0917:             * @throws org.springframework.dao.DataAccessException in case of script execution errors
0918:             * @see org.hibernate.cfg.Configuration#generateDropSchemaScript
0919:             * @see org.hibernate.tool.hbm2ddl.SchemaExport#drop
0920:             */
0921:            public void dropDatabaseSchema() throws DataAccessException {
0922:                logger
0923:                        .info("Dropping database schema for Hibernate SessionFactory");
0924:                HibernateTemplate hibernateTemplate = new HibernateTemplate(
0925:                        getSessionFactory());
0926:                hibernateTemplate.execute(new HibernateCallback() {
0927:                    public Object doInHibernate(Session session)
0928:                            throws HibernateException, SQLException {
0929:                        Connection con = session.connection();
0930:                        Dialect dialect = Dialect.getDialect(getConfiguration()
0931:                                .getProperties());
0932:                        String[] sql = getConfiguration()
0933:                                .generateDropSchemaScript(dialect);
0934:                        executeSchemaScript(con, sql);
0935:                        return null;
0936:                    }
0937:                });
0938:            }
0939:
0940:            /**
0941:             * Execute schema creation script, determined by the Configuration object
0942:             * used for creating the SessionFactory. A replacement for Hibernate's
0943:             * SchemaExport class, to be invoked on application setup.
0944:             * <p>Fetch the LocalSessionFactoryBean itself rather than the exposed
0945:             * SessionFactory to be able to invoke this method, e.g. via
0946:             * <code>LocalSessionFactoryBean lsfb = (LocalSessionFactoryBean) ctx.getBean("&mySessionFactory");</code>.
0947:             * <p>Uses the SessionFactory that this bean generates for accessing a JDBC
0948:             * connection to perform the script.
0949:             * @throws DataAccessException in case of script execution errors
0950:             * @see org.hibernate.cfg.Configuration#generateSchemaCreationScript
0951:             * @see org.hibernate.tool.hbm2ddl.SchemaExport#create
0952:             */
0953:            public void createDatabaseSchema() throws DataAccessException {
0954:                logger
0955:                        .info("Creating database schema for Hibernate SessionFactory");
0956:                HibernateTemplate hibernateTemplate = new HibernateTemplate(
0957:                        getSessionFactory());
0958:                hibernateTemplate.execute(new HibernateCallback() {
0959:                    public Object doInHibernate(Session session)
0960:                            throws HibernateException, SQLException {
0961:                        Connection con = session.connection();
0962:                        Dialect dialect = Dialect.getDialect(getConfiguration()
0963:                                .getProperties());
0964:                        String[] sql = getConfiguration()
0965:                                .generateSchemaCreationScript(dialect);
0966:                        executeSchemaScript(con, sql);
0967:                        return null;
0968:                    }
0969:                });
0970:            }
0971:
0972:            /**
0973:             * Execute schema update script, determined by the Configuration object
0974:             * used for creating the SessionFactory. A replacement for Hibernate's
0975:             * SchemaUpdate class, for automatically executing schema update scripts
0976:             * on application startup. Can also be invoked manually.
0977:             * <p>Fetch the LocalSessionFactoryBean itself rather than the exposed
0978:             * SessionFactory to be able to invoke this method, e.g. via
0979:             * <code>LocalSessionFactoryBean lsfb = (LocalSessionFactoryBean) ctx.getBean("&mySessionFactory");</code>.
0980:             * <p>Uses the SessionFactory that this bean generates for accessing a JDBC
0981:             * connection to perform the script.
0982:             * @throws DataAccessException in case of script execution errors
0983:             * @see #setSchemaUpdate
0984:             * @see org.hibernate.cfg.Configuration#generateSchemaUpdateScript
0985:             * @see org.hibernate.tool.hbm2ddl.SchemaUpdate
0986:             */
0987:            public void updateDatabaseSchema() throws DataAccessException {
0988:                logger
0989:                        .info("Updating database schema for Hibernate SessionFactory");
0990:                HibernateTemplate hibernateTemplate = new HibernateTemplate(
0991:                        getSessionFactory());
0992:                hibernateTemplate.setFlushMode(HibernateTemplate.FLUSH_NEVER);
0993:                hibernateTemplate.execute(new HibernateCallback() {
0994:                    public Object doInHibernate(Session session)
0995:                            throws HibernateException, SQLException {
0996:                        Connection con = session.connection();
0997:                        Dialect dialect = Dialect.getDialect(getConfiguration()
0998:                                .getProperties());
0999:                        DatabaseMetadata metadata = new DatabaseMetadata(con,
1000:                                dialect);
1001:                        String[] sql = getConfiguration()
1002:                                .generateSchemaUpdateScript(dialect, metadata);
1003:                        executeSchemaScript(con, sql);
1004:                        return null;
1005:                    }
1006:                });
1007:            }
1008:
1009:            /**
1010:             * Execute the given schema script on the given JDBC Connection.
1011:             * <p>Note that the default implementation will log unsuccessful statements
1012:             * and continue to execute. Override the <code>executeSchemaStatement</code>
1013:             * method to treat failures differently.
1014:             * @param con the JDBC Connection to execute the script on
1015:             * @param sql the SQL statements to execute
1016:             * @throws SQLException if thrown by JDBC methods
1017:             * @see #executeSchemaStatement
1018:             */
1019:            protected void executeSchemaScript(Connection con, String[] sql)
1020:                    throws SQLException {
1021:                if (sql != null && sql.length > 0) {
1022:                    boolean oldAutoCommit = con.getAutoCommit();
1023:                    if (!oldAutoCommit) {
1024:                        con.setAutoCommit(true);
1025:                    }
1026:                    try {
1027:                        Statement stmt = con.createStatement();
1028:                        try {
1029:                            for (int i = 0; i < sql.length; i++) {
1030:                                executeSchemaStatement(stmt, sql[i]);
1031:                            }
1032:                        } finally {
1033:                            JdbcUtils.closeStatement(stmt);
1034:                        }
1035:                    } finally {
1036:                        if (!oldAutoCommit) {
1037:                            con.setAutoCommit(false);
1038:                        }
1039:                    }
1040:                }
1041:            }
1042:
1043:            /**
1044:             * Execute the given schema SQL on the given JDBC Statement.
1045:             * <p>Note that the default implementation will log unsuccessful statements
1046:             * and continue to execute. Override this method to treat failures differently.
1047:             * @param stmt the JDBC Statement to execute the SQL on
1048:             * @param sql the SQL statement to execute
1049:             * @throws SQLException if thrown by JDBC methods (and considered fatal)
1050:             */
1051:            protected void executeSchemaStatement(Statement stmt, String sql)
1052:                    throws SQLException {
1053:                if (logger.isDebugEnabled()) {
1054:                    logger.debug("Executing schema statement: " + sql);
1055:                }
1056:                try {
1057:                    stmt.executeUpdate(sql);
1058:                } catch (SQLException ex) {
1059:                    if (logger.isWarnEnabled()) {
1060:                        logger
1061:                                .warn("Unsuccessful schema statement: " + sql,
1062:                                        ex);
1063:                    }
1064:                }
1065:            }
1066:
1067:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.