|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2011 the original author or authors. |
| 2 | + * Copyright 2002-2012 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
22 | 22 | import javax.persistence.Entity;
|
23 | 23 | import javax.persistence.MappedSuperclass;
|
24 | 24 | import javax.sql.DataSource;
|
| 25 | +import javax.transaction.TransactionManager; |
25 | 26 |
|
26 | 27 | import org.hibernate.HibernateException;
|
27 | 28 | import org.hibernate.MappingException;
|
28 | 29 | import org.hibernate.SessionFactory;
|
| 30 | +import org.hibernate.cfg.AvailableSettings; |
29 | 31 | import org.hibernate.cfg.Configuration;
|
30 | 32 | import org.hibernate.cfg.Environment;
|
| 33 | +import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory; |
| 34 | +import org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform; |
31 | 35 |
|
32 | 36 | import org.springframework.core.io.Resource;
|
33 | 37 | import org.springframework.core.io.ResourceLoader;
|
|
39 | 43 | import org.springframework.core.type.classreading.MetadataReaderFactory;
|
40 | 44 | import org.springframework.core.type.filter.AnnotationTypeFilter;
|
41 | 45 | import org.springframework.core.type.filter.TypeFilter;
|
| 46 | +import org.springframework.transaction.jta.JtaTransactionManager; |
| 47 | +import org.springframework.util.Assert; |
42 | 48 | import org.springframework.util.ClassUtils;
|
43 | 49 | import org.springframework.util.ReflectionUtils;
|
44 | 50 |
|
|
50 | 56 | * <p>This is designed for programmatic use, e.g. in {@code @Bean} factory methods.
|
51 | 57 | * Consider using {@link LocalSessionFactoryBean} for XML bean definition files.
|
52 | 58 | *
|
| 59 | + * <p><b>NOTE:</b> To set up Hibernate 4 for Spring-driven JTA transactions, make |
| 60 | + * sure to either use the {@link #setJtaTransactionManager} method or to set the |
| 61 | + * "hibernate.transaction.factory_class" property to {@link CMTTransactionFactory}. |
| 62 | + * Otherwise, Hibernate's smart flushing mechanism won't work properly. |
| 63 | + * |
53 | 64 | * @author Juergen Hoeller
|
54 | 65 | * @since 3.1
|
55 | 66 | * @see LocalSessionFactoryBean
|
@@ -97,18 +108,60 @@ public LocalSessionFactoryBuilder(DataSource dataSource, ClassLoader classLoader
|
97 | 108 | * Create a new LocalSessionFactoryBuilder for the given DataSource.
|
98 | 109 | * @param dataSource the JDBC DataSource that the resulting Hibernate SessionFactory should be using
|
99 | 110 | * (may be <code>null</code>)
|
100 |
| - * @param classLoader the ResourceLoader to load application classes from |
| 111 | + * @param resourceLoader the ResourceLoader to load application classes from |
101 | 112 | */
|
102 | 113 | public LocalSessionFactoryBuilder(DataSource dataSource, ResourceLoader resourceLoader) {
|
103 | 114 | getProperties().put(Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName());
|
104 | 115 | if (dataSource != null) {
|
105 | 116 | getProperties().put(Environment.DATASOURCE, dataSource);
|
106 | 117 | }
|
107 |
| - getProperties().put("hibernate.classLoader.application", resourceLoader.getClassLoader()); |
| 118 | + getProperties().put(AvailableSettings.APP_CLASSLOADER, resourceLoader.getClassLoader()); |
108 | 119 | this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
|
109 | 120 | }
|
110 | 121 |
|
111 | 122 |
|
| 123 | + /** |
| 124 | + * Set the Spring {@link JtaTransactionManager} or the JTA {@link TransactionManager} |
| 125 | + * to be used with Hibernate, if any. Allows for using a Spring-managed transaction |
| 126 | + * manager for Hibernate 4's session and cache synchronization, with the |
| 127 | + * "hibernate.transaction.jta.platform" automatically set to it. Also sets |
| 128 | + * "hibernate.transaction.factory_class" to {@link CMTTransactionFactory}, |
| 129 | + * instructing Hibernate to interact with externally managed transactions. |
| 130 | + * <p>A passed-in Spring {@link JtaTransactionManager} needs to contain a JTA |
| 131 | + * {@link TransactionManager} reference to be usable here, except for the WebSphere |
| 132 | + * case where we'll automatically set {@link WebSphereExtendedJtaPlatform} accordingly. |
| 133 | + * <p>Note: If this is set, the Hibernate settings should not contain a JTA platform |
| 134 | + * setting to avoid meaningless double configuration. |
| 135 | + */ |
| 136 | + public LocalSessionFactoryBuilder setJtaTransactionManager(Object jtaTransactionManager) { |
| 137 | + Assert.notNull(jtaTransactionManager, "Transaction manager reference must not be null"); |
| 138 | + if (jtaTransactionManager instanceof JtaTransactionManager) { |
| 139 | + boolean webspherePresent = ClassUtils.isPresent("com.ibm.wsspi.uow.UOWManager", getClass().getClassLoader()); |
| 140 | + if (webspherePresent) { |
| 141 | + getProperties().put(AvailableSettings.JTA_PLATFORM, new WebSphereExtendedJtaPlatform()); |
| 142 | + } |
| 143 | + else { |
| 144 | + JtaTransactionManager jtaTm = (JtaTransactionManager) jtaTransactionManager; |
| 145 | + if (jtaTm.getTransactionManager() == null) { |
| 146 | + throw new IllegalArgumentException( |
| 147 | + "Can only apply JtaTransactionManager which has a TransactionManager reference set"); |
| 148 | + } |
| 149 | + getProperties().put(AvailableSettings.JTA_PLATFORM, |
| 150 | + new ConfigurableJtaPlatform(jtaTm.getTransactionManager(), jtaTm.getUserTransaction())); |
| 151 | + } |
| 152 | + } |
| 153 | + else if (jtaTransactionManager instanceof TransactionManager) { |
| 154 | + getProperties().put(AvailableSettings.JTA_PLATFORM, |
| 155 | + new ConfigurableJtaPlatform((TransactionManager) jtaTransactionManager, null)); |
| 156 | + } |
| 157 | + else { |
| 158 | + throw new IllegalArgumentException( |
| 159 | + "Unknown transaction manager type: " + jtaTransactionManager.getClass().getName()); |
| 160 | + } |
| 161 | + getProperties().put(AvailableSettings.TRANSACTION_STRATEGY, new CMTTransactionFactory()); |
| 162 | + return this; |
| 163 | + } |
| 164 | + |
112 | 165 | /**
|
113 | 166 | * Add the given annotated classes in a batch.
|
114 | 167 | * @see #addAnnotatedClass
|
|
0 commit comments