Source Code Cross Referenced for LocalSessionFactoryBean.java in  » J2EE » spring-framework-2.0.6 » org » springframework » orm » hibernate » 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.hibernate 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002-2007 the original author or authors.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:
017:        package org.springframework.orm.hibernate;
018:
019:        import java.io.File;
020:        import java.io.IOException;
021:        import java.sql.Connection;
022:        import java.sql.SQLException;
023:        import java.sql.Statement;
024:        import java.util.Properties;
025:
026:        import javax.sql.DataSource;
027:        import javax.transaction.TransactionManager;
028:
029:        import net.sf.hibernate.HibernateException;
030:        import net.sf.hibernate.Interceptor;
031:        import net.sf.hibernate.Session;
032:        import net.sf.hibernate.SessionFactory;
033:        import net.sf.hibernate.cfg.Configuration;
034:        import net.sf.hibernate.cfg.Environment;
035:        import net.sf.hibernate.cfg.NamingStrategy;
036:        import net.sf.hibernate.dialect.Dialect;
037:        import net.sf.hibernate.tool.hbm2ddl.DatabaseMetadata;
038:        import org.apache.commons.logging.Log;
039:        import org.apache.commons.logging.LogFactory;
040:
041:        import org.springframework.beans.factory.DisposableBean;
042:        import org.springframework.beans.factory.FactoryBean;
043:        import org.springframework.beans.factory.InitializingBean;
044:        import org.springframework.core.io.ClassPathResource;
045:        import org.springframework.core.io.Resource;
046:        import org.springframework.dao.DataAccessException;
047:        import org.springframework.jdbc.support.JdbcUtils;
048:        import org.springframework.jdbc.support.lob.LobHandler;
049:
050:        /**
051:         * {@link org.springframework.beans.factory.FactoryBean} that creates a
052:         * Hibernate {@link net.sf.hibernate.SessionFactory}. This is the usual way to
053:         * set up a shared Hibernate SessionFactory in a Spring application context;
054:         * the SessionFactory can then be passed to Hibernate-based DAOs via
055:         * dependency injection.
056:         *
057:         * <p>Configuration settings can either be read from a Hibernate XML file,
058:         * specified as "configLocation", or completely via this class. A typical
059:         * local configuration consists of one or more "mappingResources", various
060:         * "hibernateProperties" (not strictly necessary), and a "dataSource" that the
061:         * SessionFactory should use. The latter can also be specified via Hibernate
062:         * properties, but "dataSource" supports any Spring-configured DataSource,
063:         * instead of relying on Hibernate's own connection providers.
064:         *
065:         * <p>This SessionFactory handling strategy is appropriate for most types of
066:         * applications, from Hibernate-only single database apps to ones that need
067:         * distributed transactions. Either {@link HibernateTransactionManager} or
068:         * {@link org.springframework.transaction.jta.JtaTransactionManager} can be
069:         * used for transaction demarcation, with the latter only necessary for
070:         * transactions which span multiple databases.
071:         *
072:         * <p>Note: Spring's Hibernate support in this package requires Hibernate 2.1.
073:         * Dedicated Hibernate3 support can be found in a separate package:
074:         * <code>org.springframework.orm.hibernate3</code>.
075:         *
076:         * @author Juergen Hoeller
077:         * @since 05.05.2003
078:         * @see HibernateTemplate#setSessionFactory
079:         * @see HibernateTransactionManager#setSessionFactory
080:         */
081:        public class LocalSessionFactoryBean implements  FactoryBean,
082:                InitializingBean, DisposableBean {
083:
084:            private static final ThreadLocal configTimeDataSourceHolder = new ThreadLocal();
085:
086:            private static final ThreadLocal configTimeTransactionManagerHolder = new ThreadLocal();
087:
088:            private static final ThreadLocal configTimeLobHandlerHolder = new ThreadLocal();
089:
090:            /**
091:             * Return the DataSource for the currently configured Hibernate SessionFactory,
092:             * to be used by LocalDataSourceConnectionProvoder.
093:             * <p>This instance will be set before initialization of the corresponding
094:             * SessionFactory, and reset immediately afterwards. It is thus only available
095:             * during configuration.
096:             * @see #setDataSource
097:             * @see LocalDataSourceConnectionProvider
098:             */
099:            public static DataSource getConfigTimeDataSource() {
100:                return (DataSource) configTimeDataSourceHolder.get();
101:            }
102:
103:            /**
104:             * Return the JTA TransactionManager for the currently configured Hibernate
105:             * SessionFactory, to be used by LocalTransactionManagerLookup.
106:             * <p>This instance will be set before initialization of the corresponding
107:             * SessionFactory, and reset immediately afterwards. It is thus only available
108:             * during configuration.
109:             * @see #setJtaTransactionManager
110:             * @see LocalTransactionManagerLookup
111:             */
112:            public static TransactionManager getConfigTimeTransactionManager() {
113:                return (TransactionManager) configTimeTransactionManagerHolder
114:                        .get();
115:            }
116:
117:            /**
118:             * Return the LobHandler for the currently configured Hibernate SessionFactory,
119:             * to be used by UserType implementations like ClobStringType.
120:             * <p>This instance will be set before initialization of the corresponding
121:             * SessionFactory, and reset immediately afterwards. It is thus only available
122:             * during configuration.
123:             * @see #setLobHandler
124:             * @see org.springframework.orm.hibernate.support.ClobStringType
125:             * @see org.springframework.orm.hibernate.support.BlobByteArrayType
126:             * @see org.springframework.orm.hibernate.support.BlobSerializableType
127:             */
128:            public static LobHandler getConfigTimeLobHandler() {
129:                return (LobHandler) configTimeLobHandlerHolder.get();
130:            }
131:
132:            protected final Log logger = LogFactory.getLog(getClass());
133:
134:            private Resource configLocation;
135:
136:            private Resource[] mappingLocations;
137:
138:            private Resource[] mappingJarLocations;
139:
140:            private Resource[] mappingDirectoryLocations;
141:
142:            private Properties hibernateProperties;
143:
144:            private DataSource dataSource;
145:
146:            private boolean useTransactionAwareDataSource = false;
147:
148:            private TransactionManager jtaTransactionManager;
149:
150:            private LobHandler lobHandler;
151:
152:            private Interceptor entityInterceptor;
153:
154:            private NamingStrategy namingStrategy;
155:
156:            private boolean schemaUpdate = false;
157:
158:            private Configuration configuration;
159:
160:            private SessionFactory sessionFactory;
161:
162:            /**
163:             * Set the location of the Hibernate XML config file, for example as
164:             * classpath resource "classpath:hibernate.cfg.xml".
165:             * <p>Note: Can be omitted when all necessary properties and mapping
166:             * resources are specified locally via this bean.
167:             * @see net.sf.hibernate.cfg.Configuration#configure(java.net.URL)
168:             */
169:            public void setConfigLocation(Resource configLocation) {
170:                this .configLocation = configLocation;
171:            }
172:
173:            /**
174:             * Set Hibernate mapping resources to be found in the class path,
175:             * like "example.hbm.xml" or "mypackage/example.hbm.xml".
176:             * Analogous to mapping entries in a Hibernate XML config file.
177:             * Alternative to the more generic setMappingLocations method.
178:             * <p>Can be used to add to mappings from a Hibernate XML config file,
179:             * or to specify all mappings locally.
180:             * @see #setMappingLocations
181:             * @see net.sf.hibernate.cfg.Configuration#addResource
182:             */
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(
187:                            mappingResources[i].trim());
188:                }
189:            }
190:
191:            /**
192:             * Set locations of Hibernate mapping files, for example as classpath
193:             * resource "classpath:example.hbm.xml". Supports any resource location
194:             * via Spring's resource abstraction, for example relative paths like
195:             * "WEB-INF/mappings/example.hbm.xml" when running in an application context.
196:             * <p>Can be used to add to mappings from a Hibernate XML config file,
197:             * or to specify all mappings locally.
198:             * @see net.sf.hibernate.cfg.Configuration#addInputStream
199:             */
200:            public void setMappingLocations(Resource[] mappingLocations) {
201:                this .mappingLocations = mappingLocations;
202:            }
203:
204:            /**
205:             * Set locations of jar files that contain Hibernate mapping resources,
206:             * like "WEB-INF/lib/example.hbm.jar".
207:             * <p>Can be used to add to mappings from a Hibernate XML config file,
208:             * or to specify all mappings locally.
209:             * @see net.sf.hibernate.cfg.Configuration#addJar(java.io.File)
210:             */
211:            public void setMappingJarLocations(Resource[] mappingJarLocations) {
212:                this .mappingJarLocations = mappingJarLocations;
213:            }
214:
215:            /**
216:             * Set locations of directories that contain Hibernate mapping resources,
217:             * like "WEB-INF/mappings".
218:             * <p>Can be used to add to mappings from a Hibernate XML config file,
219:             * or to specify all mappings locally.
220:             * @see net.sf.hibernate.cfg.Configuration#addDirectory(java.io.File)
221:             */
222:            public void setMappingDirectoryLocations(
223:                    Resource[] mappingDirectoryLocations) {
224:                this .mappingDirectoryLocations = mappingDirectoryLocations;
225:            }
226:
227:            /**
228:             * Set Hibernate properties, such as "hibernate.dialect".
229:             * <p>Can be used to override values in a Hibernate XML config file,
230:             * or to specify all necessary properties locally.
231:             * <p>Note: Do not specify a transaction provider here when using
232:             * Spring-driven transactions. It is also advisable to omit connection
233:             * provider settings and use a Spring-set DataSource instead.
234:             * @see #setDataSource
235:             */
236:            public void setHibernateProperties(Properties hibernateProperties) {
237:                this .hibernateProperties = hibernateProperties;
238:            }
239:
240:            /**
241:             * Return the Hibernate properties, if any. Mainly available for
242:             * configuration through property paths that specify individual keys.
243:             */
244:            public Properties getHibernateProperties() {
245:                if (this .hibernateProperties == null) {
246:                    this .hibernateProperties = new Properties();
247:                }
248:                return this .hibernateProperties;
249:            }
250:
251:            /**
252:             * Set the DataSource to be used by the SessionFactory.
253:             * If set, this will override corresponding settings in Hibernate properties.
254:             * <p>Note: If this is set, the Hibernate settings should not define
255:             * a connection provider to avoid meaningless double configuration.
256:             * <p>If using HibernateTransactionManager as transaction strategy, consider
257:             * proxying your target DataSource with a LazyConnectionDataSourceProxy.
258:             * This defers fetching of an actual JDBC Connection until the first JDBC
259:             * Statement gets executed, even within JDBC transactions (as performed by
260:             * HibernateTransactionManager). Such lazy fetching is particularly beneficial
261:             * for read-only operations, in particular if the chances of resolving the
262:             * result in the second-level cache are high.
263:             * <p>As JTA and transactional JNDI DataSources already provide lazy enlistment
264:             * of JDBC Connections, LazyConnectionDataSourceProxy does not add value with
265:             * JTA (i.e. Spring's JtaTransactionManager) as transaction strategy.
266:             * @see #setUseTransactionAwareDataSource
267:             * @see LocalDataSourceConnectionProvider
268:             * @see HibernateTransactionManager
269:             * @see org.springframework.transaction.jta.JtaTransactionManager
270:             * @see org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy
271:             */
272:            public void setDataSource(DataSource dataSource) {
273:                this .dataSource = dataSource;
274:            }
275:
276:            /**
277:             * Set whether to use a transaction-aware DataSource for the SessionFactory,
278:             * i.e. whether to automatically wrap the passed-in DataSource with Spring's
279:             * TransactionAwareDataSourceProxy.
280:             * <p>Default is "false": LocalSessionFactoryBean is usually used with Spring's
281:             * HibernateTransactionManager or JtaTransactionManager, both of which work nicely
282:             * on a plain JDBC DataSource. Hibernate Sessions and their JDBC Connections are
283:             * fully managed by the Hibernate/JTA transaction infrastructure in such a scenario.
284:             * <p>If you switch this flag to "true", Spring's Hibernate access will be able to
285:             * <i>participate in JDBC-based transactions managed outside of Hibernate</i>
286:             * (for example, by Spring's DataSourceTransactionManager). This can be convenient
287:             * if you need a different local transaction strategy for another O/R mapping tool,
288:             * for example, but still want Hibernate access to join into those transactions.
289:             * <p>A further benefit of this option is that <i>plain Sessions opened directly
290:             * via the SessionFactory</i>, outside of Spring's Hibernate support, will still
291:             * participate in active Spring-managed transactions.
292:             * <p>As a further effect, using a transaction-aware DataSource will <i>apply
293:             * remaining transaction timeouts to all created JDBC Statements</i>. This means
294:             * that all operations performed by the SessionFactory will automatically
295:             * participate in Spring-managed transaction timeouts, not just queries.
296:             * This adds value even for HibernateTransactionManager.
297:             * <p><b>WARNING: Be aware of side effects when using a transaction-aware
298:             * DataSource in combination with OpenSessionInViewFilter/Interceptor.</b>
299:             * This combination is only properly supported with HibernateTransactionManager
300:             * transactions. PROPAGATION_SUPPORTS with HibernateTransactionManager and
301:             * JtaTransactionManager in general are only supported on Hibernate3, which
302:             * introduces (optional) aggressive release of Connections.
303:             * @see #setDataSource
304:             * @see org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
305:             * @see org.springframework.jdbc.datasource.DataSourceTransactionManager
306:             * @see org.springframework.orm.hibernate.support.OpenSessionInViewFilter
307:             * @see org.springframework.orm.hibernate.support.OpenSessionInViewInterceptor
308:             * @see HibernateTransactionManager
309:             * @see org.springframework.transaction.jta.JtaTransactionManager
310:             * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setUseTransactionAwareDataSource
311:             */
312:            public void setUseTransactionAwareDataSource(
313:                    boolean useTransactionAwareDataSource) {
314:                this .useTransactionAwareDataSource = useTransactionAwareDataSource;
315:            }
316:
317:            /**
318:             * Set the JTA TransactionManager to be used for Hibernate's
319:             * TransactionManagerLookup. If set, this will override corresponding
320:             * settings in Hibernate properties. Allows to use a Spring-managed
321:             * JTA TransactionManager for Hibernate's cache synchronization.
322:             * <p>Note: If this is set, the Hibernate settings should not define a
323:             * transaction manager lookup to avoid meaningless double configuration.
324:             * @see LocalTransactionManagerLookup
325:             */
326:            public void setJtaTransactionManager(
327:                    TransactionManager jtaTransactionManager) {
328:                this .jtaTransactionManager = jtaTransactionManager;
329:            }
330:
331:            /**
332:             * Set the LobHandler to be used by the SessionFactory.
333:             * Will be exposed at config time for UserType implementations.
334:             * @see #getConfigTimeLobHandler
335:             * @see net.sf.hibernate.UserType
336:             * @see org.springframework.orm.hibernate.support.ClobStringType
337:             * @see org.springframework.orm.hibernate.support.BlobByteArrayType
338:             * @see org.springframework.orm.hibernate.support.BlobSerializableType
339:             */
340:            public void setLobHandler(LobHandler lobHandler) {
341:                this .lobHandler = lobHandler;
342:            }
343:
344:            /**
345:             * Set a Hibernate entity interceptor that allows to inspect and change
346:             * property values before writing to and reading from the database.
347:             * Will get applied to any new Session created by this factory.
348:             * <p>Such an interceptor can either be set at the SessionFactory level, i.e. on
349:             * LocalSessionFactoryBean, or at the Session level, i.e. on HibernateTemplate,
350:             * HibernateInterceptor, and HibernateTransactionManager. It's preferable to set
351:             * it on LocalSessionFactoryBean or HibernateTransactionManager to avoid repeated
352:             * configuration and guarantee consistent behavior in transactions.
353:             * @see HibernateTemplate#setEntityInterceptor
354:             * @see HibernateInterceptor#setEntityInterceptor
355:             * @see HibernateTransactionManager#setEntityInterceptor
356:             * @see net.sf.hibernate.cfg.Configuration#setInterceptor
357:             */
358:            public void setEntityInterceptor(Interceptor entityInterceptor) {
359:                this .entityInterceptor = entityInterceptor;
360:            }
361:
362:            /**
363:             * Set a Hibernate NamingStrategy for the SessionFactory, determining the
364:             * physical column and table names given the info in the mapping document.
365:             * @see net.sf.hibernate.cfg.Configuration#setNamingStrategy
366:             */
367:            public void setNamingStrategy(NamingStrategy namingStrategy) {
368:                this .namingStrategy = namingStrategy;
369:            }
370:
371:            /**
372:             * Set whether to execute a schema update after SessionFactory initialization.
373:             * <p>For details on how to make schema update scripts work, see the Hibernate
374:             * documentation, as this class leverages the same schema update script support
375:             * in net.sf.hibernate.cfg.Configuration as Hibernate's own SchemaUpdate tool.
376:             * @see net.sf.hibernate.cfg.Configuration#generateSchemaUpdateScript
377:             * @see net.sf.hibernate.tool.hbm2ddl.SchemaUpdate
378:             */
379:            public void setSchemaUpdate(boolean schemaUpdate) {
380:                this .schemaUpdate = schemaUpdate;
381:            }
382:
383:            /**
384:             * Initialize the SessionFactory for the given or the default location.
385:             * @throws IllegalArgumentException in case of illegal property values
386:             * @throws HibernateException in case of Hibernate initialization errors
387:             */
388:            public void afterPropertiesSet() throws IllegalArgumentException,
389:                    HibernateException, IOException {
390:                // Create Configuration instance.
391:                Configuration config = newConfiguration();
392:
393:                if (this .dataSource != null) {
394:                    // Make given DataSource available for SessionFactory configuration.
395:                    configTimeDataSourceHolder.set(this .dataSource);
396:                }
397:
398:                if (this .jtaTransactionManager != null) {
399:                    // Make Spring-provided JTA TransactionManager available.
400:                    configTimeTransactionManagerHolder
401:                            .set(this .jtaTransactionManager);
402:                }
403:
404:                if (this .lobHandler != null) {
405:                    // Make given LobHandler available for SessionFactory configuration.
406:                    // Do early because because mapping resource might refer to custom types.
407:                    configTimeLobHandlerHolder.set(this .lobHandler);
408:                }
409:
410:                try {
411:
412:                    if (this .entityInterceptor != null) {
413:                        // Set given entity interceptor at SessionFactory level.
414:                        config.setInterceptor(this .entityInterceptor);
415:                    }
416:
417:                    if (this .namingStrategy != null) {
418:                        // Pass given naming strategy to Hibernate Configuration.
419:                        config.setNamingStrategy(this .namingStrategy);
420:                    }
421:
422:                    if (this .configLocation != null) {
423:                        // Load Hibernate configuration from given location.
424:                        config.configure(this .configLocation.getURL());
425:                    }
426:
427:                    if (this .hibernateProperties != null) {
428:                        // Add given Hibernate properties to Configuration.
429:                        config.addProperties(this .hibernateProperties);
430:                    }
431:
432:                    if (this .dataSource != null) {
433:                        // Set Spring-provided DataSource as Hibernate property.
434:                        config
435:                                .setProperty(
436:                                        Environment.CONNECTION_PROVIDER,
437:                                        this .useTransactionAwareDataSource ? TransactionAwareDataSourceConnectionProvider.class
438:                                                .getName()
439:                                                : LocalDataSourceConnectionProvider.class
440:                                                        .getName());
441:                    }
442:
443:                    if (this .jtaTransactionManager != null) {
444:                        // Set Spring-provided JTA TransactionManager as Hibernate property.
445:                        config.setProperty(
446:                                Environment.TRANSACTION_MANAGER_STRATEGY,
447:                                LocalTransactionManagerLookup.class.getName());
448:                    }
449:
450:                    if (this .mappingLocations != null) {
451:                        // Register given Hibernate mapping definitions, contained in resource files.
452:                        for (int i = 0; i < this .mappingLocations.length; i++) {
453:                            config.addInputStream(this .mappingLocations[i]
454:                                    .getInputStream());
455:                        }
456:                    }
457:
458:                    if (this .mappingJarLocations != null) {
459:                        // Register given Hibernate mapping definitions, contained in jar files.
460:                        for (int i = 0; i < this .mappingJarLocations.length; i++) {
461:                            Resource resource = this .mappingJarLocations[i];
462:                            config.addJar(resource.getFile());
463:                        }
464:                    }
465:
466:                    if (this .mappingDirectoryLocations != null) {
467:                        // Register all Hibernate mapping definitions in the given directories.
468:                        for (int i = 0; i < this .mappingDirectoryLocations.length; i++) {
469:                            File file = this .mappingDirectoryLocations[i]
470:                                    .getFile();
471:                            if (!file.isDirectory()) {
472:                                throw new IllegalArgumentException(
473:                                        "Mapping directory location ["
474:                                                + this .mappingDirectoryLocations[i]
475:                                                + "] does not denote a directory");
476:                            }
477:                            config.addDirectory(file);
478:                        }
479:                    }
480:
481:                    // Perform custom post-processing in subclasses.
482:                    postProcessConfiguration(config);
483:
484:                    // Build SessionFactory instance.
485:                    logger.info("Building new Hibernate SessionFactory");
486:                    this .configuration = config;
487:                    this .sessionFactory = newSessionFactory(config);
488:                }
489:
490:                finally {
491:                    if (this .dataSource != null) {
492:                        // Reset DataSource holder.
493:                        configTimeDataSourceHolder.set(null);
494:                    }
495:
496:                    if (this .jtaTransactionManager != null) {
497:                        // Reset TransactionManager holder.
498:                        configTimeTransactionManagerHolder.set(null);
499:                    }
500:
501:                    if (this .lobHandler != null) {
502:                        // Reset LobHandler holder.
503:                        configTimeLobHandlerHolder.set(null);
504:                    }
505:                }
506:
507:                // Execute schema update if requested.
508:                if (this .schemaUpdate) {
509:                    updateDatabaseSchema();
510:                }
511:            }
512:
513:            /**
514:             * Subclasses can override this method to perform custom initialization
515:             * of the Configuration instance used for SessionFactory creation.
516:             * The properties of this LocalSessionFactoryBean will be applied to
517:             * the Configuration object that gets returned here.
518:             * <p>The default implementation creates a new Configuration instance.
519:             * A custom implementation could prepare the instance in a specific way,
520:             * or use a custom Configuration subclass.
521:             * @return the Configuration instance
522:             * @throws HibernateException in case of Hibernate initialization errors
523:             * @see net.sf.hibernate.cfg.Configuration#Configuration()
524:             */
525:            protected Configuration newConfiguration()
526:                    throws HibernateException {
527:                return new Configuration();
528:            }
529:
530:            /**
531:             * To be implemented by subclasses that want to to perform custom
532:             * post-processing of the Configuration object after this FactoryBean
533:             * performed its default initialization.
534:             * @param config the current Configuration object
535:             * @throws HibernateException in case of Hibernate initialization errors
536:             */
537:            protected void postProcessConfiguration(Configuration config)
538:                    throws HibernateException {
539:            }
540:
541:            /**
542:             * Subclasses can override this method to perform custom initialization
543:             * of the SessionFactory instance, creating it via the given Configuration
544:             * object that got prepared by this LocalSessionFactoryBean.
545:             * <p>The default implementation invokes Configuration's buildSessionFactory.
546:             * A custom implementation could prepare the instance in a specific way,
547:             * or use a custom SessionFactoryImpl subclass.
548:             * @param config Configuration prepared by this LocalSessionFactoryBean
549:             * @return the SessionFactory instance
550:             * @throws HibernateException in case of Hibernate initialization errors
551:             * @see net.sf.hibernate.cfg.Configuration#buildSessionFactory
552:             */
553:            protected SessionFactory newSessionFactory(Configuration config)
554:                    throws HibernateException {
555:                return config.buildSessionFactory();
556:            }
557:
558:            /**
559:             * Execute schema drop script, determined by the Configuration object
560:             * used for creating the SessionFactory. A replacement for Hibernate's
561:             * SchemaExport class, to be invoked on application setup.
562:             * <p>Fetch the LocalSessionFactoryBean itself rather than the exposed
563:             * SessionFactory to be able to invoke this method, e.g. via
564:             * <code>LocalSessionFactoryBean lsfb = (LocalSessionFactoryBean) ctx.getBean("&mySessionFactory");</code>.
565:             * <p>Uses the SessionFactory that this bean generates for accessing a JDBC
566:             * connection to perform the script.
567:             * @throws DataAccessException in case of script execution errors
568:             * @see net.sf.hibernate.cfg.Configuration#generateDropSchemaScript
569:             * @see net.sf.hibernate.tool.hbm2ddl.SchemaExport#drop
570:             */
571:            public void dropDatabaseSchema() throws DataAccessException {
572:                logger
573:                        .info("Dropping database schema for Hibernate SessionFactory");
574:                HibernateTemplate hibernateTemplate = new HibernateTemplate(
575:                        this .sessionFactory);
576:                hibernateTemplate.execute(new HibernateCallback() {
577:                    public Object doInHibernate(Session session)
578:                            throws HibernateException, SQLException {
579:                        Connection con = session.connection();
580:                        Dialect dialect = Dialect.getDialect(configuration
581:                                .getProperties());
582:                        String[] sql = configuration
583:                                .generateDropSchemaScript(dialect);
584:                        executeSchemaScript(con, sql);
585:                        return null;
586:                    }
587:                });
588:            }
589:
590:            /**
591:             * Execute schema creation script, determined by the Configuration object
592:             * used for creating the SessionFactory. A replacement for Hibernate's
593:             * SchemaExport class, to be invoked on application setup.
594:             * <p>Fetch the LocalSessionFactoryBean itself rather than the exposed
595:             * SessionFactory to be able to invoke this method, e.g. via
596:             * <code>LocalSessionFactoryBean lsfb = (LocalSessionFactoryBean) ctx.getBean("&mySessionFactory");</code>.
597:             * <p>Uses the SessionFactory that this bean generates for accessing a JDBC
598:             * connection to perform the script.
599:             * @throws DataAccessException in case of script execution errors
600:             * @see net.sf.hibernate.cfg.Configuration#generateSchemaCreationScript
601:             * @see net.sf.hibernate.tool.hbm2ddl.SchemaExport#create
602:             */
603:            public void createDatabaseSchema() throws DataAccessException {
604:                logger
605:                        .info("Creating database schema for Hibernate SessionFactory");
606:                HibernateTemplate hibernateTemplate = new HibernateTemplate(
607:                        this .sessionFactory);
608:                hibernateTemplate.execute(new HibernateCallback() {
609:                    public Object doInHibernate(Session session)
610:                            throws HibernateException, SQLException {
611:                        Connection con = session.connection();
612:                        Dialect dialect = Dialect.getDialect(configuration
613:                                .getProperties());
614:                        String[] sql = configuration
615:                                .generateSchemaCreationScript(dialect);
616:                        executeSchemaScript(con, sql);
617:                        return null;
618:                    }
619:                });
620:            }
621:
622:            /**
623:             * Execute schema update script, determined by the Configuration object
624:             * used for creating the SessionFactory. A replacement for Hibernate's
625:             * SchemaUpdate class, for automatically executing schema update scripts
626:             * on application startup. Can also be invoked manually.
627:             * <p>Fetch the LocalSessionFactoryBean itself rather than the exposed
628:             * SessionFactory to be able to invoke this method, e.g. via
629:             * <code>LocalSessionFactoryBean lsfb = (LocalSessionFactoryBean) ctx.getBean("&mySessionFactory");</code>.
630:             * <p>Uses the SessionFactory that this bean generates for accessing a JDBC
631:             * connection to perform the script.
632:             * @throws DataAccessException in case of script execution errors
633:             * @see #setSchemaUpdate
634:             * @see net.sf.hibernate.cfg.Configuration#generateSchemaUpdateScript
635:             * @see net.sf.hibernate.tool.hbm2ddl.SchemaUpdate
636:             */
637:            public void updateDatabaseSchema() throws DataAccessException {
638:                logger
639:                        .info("Updating database schema for Hibernate SessionFactory");
640:                HibernateTemplate hibernateTemplate = new HibernateTemplate(
641:                        this .sessionFactory);
642:                hibernateTemplate.setFlushMode(HibernateTemplate.FLUSH_NEVER);
643:                hibernateTemplate.execute(new HibernateCallback() {
644:                    public Object doInHibernate(Session session)
645:                            throws HibernateException, SQLException {
646:                        Connection con = session.connection();
647:                        Dialect dialect = Dialect.getDialect(configuration
648:                                .getProperties());
649:                        DatabaseMetadata metadata = new DatabaseMetadata(con,
650:                                dialect);
651:                        String[] sql = configuration
652:                                .generateSchemaUpdateScript(dialect, metadata);
653:                        executeSchemaScript(con, sql);
654:                        return null;
655:                    }
656:                });
657:            }
658:
659:            /**
660:             * Execute the given schema script on the given JDBC Connection.
661:             * <p>Note that the default implementation will log unsuccessful statements
662:             * and continue to execute. Override the <code>executeSchemaStatement</code>
663:             * method to treat failures differently.
664:             * @param con the JDBC Connection to execute the script on
665:             * @param sql the SQL statements to execute
666:             * @throws SQLException if thrown by JDBC methods
667:             * @see #executeSchemaStatement
668:             */
669:            protected void executeSchemaScript(Connection con, String[] sql)
670:                    throws SQLException {
671:                if (sql != null && sql.length > 0) {
672:                    boolean oldAutoCommit = con.getAutoCommit();
673:                    if (!oldAutoCommit) {
674:                        con.setAutoCommit(true);
675:                    }
676:                    try {
677:                        Statement stmt = con.createStatement();
678:                        try {
679:                            for (int i = 0; i < sql.length; i++) {
680:                                executeSchemaStatement(stmt, sql[i]);
681:                            }
682:                        } finally {
683:                            JdbcUtils.closeStatement(stmt);
684:                        }
685:                    } finally {
686:                        if (!oldAutoCommit) {
687:                            con.setAutoCommit(false);
688:                        }
689:                    }
690:                }
691:            }
692:
693:            /**
694:             * Execute the given schema SQL on the given JDBC Statement.
695:             * <p>Note that the default implementation will log unsuccessful statements
696:             * and continue to execute. Override this method to treat failures differently.
697:             * @param stmt the JDBC Statement to execute the SQL on
698:             * @param sql the SQL statement to execute
699:             * @throws SQLException if thrown by JDBC methods (and considered fatal)
700:             */
701:            protected void executeSchemaStatement(Statement stmt, String sql)
702:                    throws SQLException {
703:                if (logger.isDebugEnabled()) {
704:                    logger.debug("Executing schema statement: " + sql);
705:                }
706:                try {
707:                    stmt.executeUpdate(sql);
708:                } catch (SQLException ex) {
709:                    if (logger.isWarnEnabled()) {
710:                        logger
711:                                .warn("Unsuccessful schema statement: " + sql,
712:                                        ex);
713:                    }
714:                }
715:            }
716:
717:            /**
718:             * Return the Configuration object used to build the SessionFactory.
719:             * Allows access to configuration metadata stored there (rarely needed).
720:             */
721:            public Configuration getConfiguration() {
722:                return configuration;
723:            }
724:
725:            /**
726:             * Return the singleton SessionFactory.
727:             */
728:            public Object getObject() {
729:                return this .sessionFactory;
730:            }
731:
732:            public Class getObjectType() {
733:                return (this .sessionFactory != null) ? this .sessionFactory
734:                        .getClass() : SessionFactory.class;
735:            }
736:
737:            public boolean isSingleton() {
738:                return true;
739:            }
740:
741:            /**
742:             * Close the SessionFactory on bean factory shutdown.
743:             */
744:            public void destroy() throws HibernateException {
745:                logger.info("Closing Hibernate SessionFactory");
746:                if (this .dataSource != null) {
747:                    // Make given DataSource available for potential SchemaExport,
748:                    // which unfortunately reinstantiates a ConnectionProvider.
749:                    configTimeDataSourceHolder.set(this .dataSource);
750:                }
751:                try {
752:                    this .sessionFactory.close();
753:                } finally {
754:                    if (this .dataSource != null) {
755:                        // Reset DataSource holder.
756:                        configTimeDataSourceHolder.set(null);
757:                    }
758:                }
759:            }
760:
761:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.