mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-17 08:24:13 +00:00
Support JtaTransactionManager/SpringBeanContainer on HibernateJpaVendorAdapter
Makes ConfigurableJtaPlatform public and removes outdated WebSphere UOW check. Closes gh-36216
This commit is contained in:
+3
-3
@@ -31,14 +31,14 @@ import org.springframework.transaction.jta.UserTransactionAdapter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Implementation of Hibernate 5's JtaPlatform SPI, exposing passed-in {@link TransactionManager},
|
||||
* Implementation of Hibernate's JtaPlatform SPI, exposing passed-in {@link TransactionManager},
|
||||
* {@link UserTransaction} and {@link TransactionSynchronizationRegistry} references.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 7.0
|
||||
* @since 7.0.4
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
class ConfigurableJtaPlatform implements JtaPlatform {
|
||||
public class ConfigurableJtaPlatform implements JtaPlatform {
|
||||
|
||||
private final TransactionManager transactionManager;
|
||||
|
||||
|
||||
+9
-16
@@ -180,32 +180,25 @@ public class LocalSessionFactoryBuilder extends Configuration {
|
||||
/**
|
||||
* Set the Spring {@link JtaTransactionManager} or the JTA {@link TransactionManager}
|
||||
* to be used with Hibernate, if any. Allows for using a Spring-managed transaction
|
||||
* manager for Hibernate 5's session and cache synchronization, with the
|
||||
* manager for Hibernate's session and cache synchronization, with the
|
||||
* "hibernate.transaction.jta.platform" automatically set to it.
|
||||
* <p>A passed-in Spring {@link JtaTransactionManager} needs to contain a JTA
|
||||
* {@link TransactionManager} reference to be usable here, except for the WebSphere
|
||||
* case where we'll automatically set {@code WebSphereExtendedJtaPlatform} accordingly.
|
||||
* {@link TransactionManager} reference to be usable here.
|
||||
* <p>Note: If this is set, the Hibernate settings should not contain a JTA platform
|
||||
* setting to avoid meaningless double configuration.
|
||||
* @see AvailableSettings#JTA_PLATFORM
|
||||
*/
|
||||
public LocalSessionFactoryBuilder setJtaTransactionManager(Object jtaTransactionManager) {
|
||||
Assert.notNull(jtaTransactionManager, "Transaction manager reference must not be null");
|
||||
|
||||
if (jtaTransactionManager instanceof JtaTransactionManager springJtaTm) {
|
||||
boolean webspherePresent = ClassUtils.isPresent("com.ibm.wsspi.uow.UOWManager", getClass().getClassLoader());
|
||||
if (webspherePresent) {
|
||||
getProperties().put(AvailableSettings.JTA_PLATFORM,
|
||||
"org.hibernate.engine.transaction.jta.platform.internal.WebSphereExtendedJtaPlatform");
|
||||
}
|
||||
else {
|
||||
if (springJtaTm.getTransactionManager() == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can only apply JtaTransactionManager which has a TransactionManager reference set");
|
||||
}
|
||||
getProperties().put(AvailableSettings.JTA_PLATFORM,
|
||||
new ConfigurableJtaPlatform(springJtaTm.getTransactionManager(), springJtaTm.getUserTransaction(),
|
||||
springJtaTm.getTransactionSynchronizationRegistry()));
|
||||
if (springJtaTm.getTransactionManager() == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can only apply JtaTransactionManager which has a TransactionManager reference set");
|
||||
}
|
||||
getProperties().put(AvailableSettings.JTA_PLATFORM,
|
||||
new ConfigurableJtaPlatform(springJtaTm.getTransactionManager(), springJtaTm.getUserTransaction(),
|
||||
springJtaTm.getTransactionSynchronizationRegistry()));
|
||||
}
|
||||
else if (jtaTransactionManager instanceof TransactionManager jtaTm) {
|
||||
getProperties().put(AvailableSettings.JTA_PLATFORM,
|
||||
|
||||
+60
-2
@@ -23,6 +23,7 @@ import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.EntityManagerFactory;
|
||||
import jakarta.persistence.spi.PersistenceProvider;
|
||||
import jakarta.persistence.spi.PersistenceUnitInfo;
|
||||
import jakarta.transaction.TransactionManager;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
@@ -38,7 +39,13 @@ import org.hibernate.dialect.SybaseDialect;
|
||||
import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.orm.jpa.hibernate.ConfigurableJtaPlatform;
|
||||
import org.springframework.orm.jpa.hibernate.SpringBeanContainer;
|
||||
import org.springframework.orm.jpa.persistenceunit.SmartPersistenceUnitInfo;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for Hibernate.
|
||||
@@ -65,7 +72,7 @@ import org.springframework.orm.jpa.persistenceunit.SmartPersistenceUnitInfo;
|
||||
* @since 2.0
|
||||
* @see HibernateJpaDialect
|
||||
*/
|
||||
public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter {
|
||||
public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter implements BeanFactoryAware {
|
||||
|
||||
private final HibernateJpaDialect jpaDialect = new HibernateJpaDialect();
|
||||
|
||||
@@ -75,6 +82,10 @@ public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter {
|
||||
|
||||
private final Class<? extends EntityManager> entityManagerInterface;
|
||||
|
||||
private @Nullable Object jtaTransactionManager;
|
||||
|
||||
private @Nullable BeanFactory beanFactory;
|
||||
|
||||
|
||||
public HibernateJpaVendorAdapter() {
|
||||
this.persistenceProvider = new SpringHibernateJpaPersistenceProvider();
|
||||
@@ -110,6 +121,29 @@ public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter {
|
||||
this.jpaDialect.setPrepareConnection(prepareConnection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Spring {@link org.springframework.transaction.jta.JtaTransactionManager}
|
||||
* or the JTA {@link jakarta.transaction.TransactionManager} to be used with Hibernate,
|
||||
* if any. Implicitly sets up {@code JtaPlatform}.
|
||||
* @since 7.0.4
|
||||
* @see AvailableSettings#JTA_PLATFORM
|
||||
*/
|
||||
public void setJtaTransactionManager(Object jtaTransactionManager) {
|
||||
this.jtaTransactionManager = jtaTransactionManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Spring {@link ConfigurableListableBeanFactory} to use for a default
|
||||
* Hibernate setup with {@link SpringBeanContainer}. This enables autowiring of
|
||||
* Hibernate attribute converters and entity listeners.
|
||||
* @since 7.0.4
|
||||
* @see AvailableSettings#BEAN_CONTAINER
|
||||
*/
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PersistenceProvider getPersistenceProvider() {
|
||||
@@ -163,7 +197,31 @@ public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter {
|
||||
PhysicalConnectionHandlingMode.DELAYED_ACQUISITION_AND_HOLD);
|
||||
}
|
||||
|
||||
// For SpringBeanContainer to be called on Hibernate 6.2
|
||||
// Derive Hibernate JtaPlatform from Spring (Jta)TransactionManager setup.
|
||||
if (this.jtaTransactionManager != null) {
|
||||
if (this.jtaTransactionManager instanceof JtaTransactionManager springJtaTm) {
|
||||
if (springJtaTm.getTransactionManager() == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can only apply JtaTransactionManager which has a TransactionManager reference set");
|
||||
}
|
||||
jpaProperties.put(AvailableSettings.JTA_PLATFORM, new ConfigurableJtaPlatform(
|
||||
springJtaTm.getTransactionManager(), springJtaTm.getUserTransaction(),
|
||||
springJtaTm.getTransactionSynchronizationRegistry()));
|
||||
}
|
||||
else if (this.jtaTransactionManager instanceof TransactionManager jtaTm) {
|
||||
jpaProperties.put(AvailableSettings.JTA_PLATFORM, new ConfigurableJtaPlatform(jtaTm, null, null));
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(
|
||||
"Unknown transaction manager type: " + this.jtaTransactionManager.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
// This enables autowiring of Hibernate attribute converters and entity listeners.
|
||||
if (this.beanFactory instanceof ConfigurableListableBeanFactory clbf) {
|
||||
jpaProperties.put(AvailableSettings.BEAN_CONTAINER, new SpringBeanContainer(clbf));
|
||||
}
|
||||
// For SpringBeanContainer to actually be called at runtime.
|
||||
jpaProperties.put("hibernate.cdi.extensions", "true");
|
||||
|
||||
return jpaProperties;
|
||||
|
||||
Reference in New Issue
Block a user