|
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