Spring boot + Spring Data JPA + Atomikos + Multiple databases configuration

匿名 (未验证) 提交于 2019-12-03 02:45:02

问题:

With this configuration (MainConfig.java):

import javax.transaction.TransactionManager; import javax.transaction.UserTransaction;  import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.vendor.Database; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.jta.JtaTransactionManager;  import com.atomikos.icatch.jta.UserTransactionImp; import com.atomikos.icatch.jta.UserTransactionManager;  @Configuration @ComponentScan public class MainConfig {      @Bean     public JpaVendorAdapter jpaVendorAdapter() {         HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();         hibernateJpaVendorAdapter.setShowSql(true);         hibernateJpaVendorAdapter.setGenerateDdl(true);         hibernateJpaVendorAdapter.setDatabase(Database.MYSQL);         return hibernateJpaVendorAdapter;     }      @Bean(name = "userTransaction")     public UserTransaction userTransaction() throws Throwable {         UserTransactionImp userTransactionImp = new UserTransactionImp();         userTransactionImp.setTransactionTimeout(10000);         return userTransactionImp;     }      @Bean(name = "atomikosTransactionManager", initMethod = "init", destroyMethod = "close")     public TransactionManager atomikosTransactionManager() throws Throwable {         UserTransactionManager userTransactionManager = new UserTransactionManager();         userTransactionManager.setForceShutdown(false);         return userTransactionManager;     }      @Bean(name = "transactionManager")     @DependsOn({ "userTransaction", "atomikosTransactionManager" })     public PlatformTransactionManager transactionManager() throws Throwable {         UserTransaction userTransaction = userTransaction();         TransactionManager atomikosTransactionManager = atomikosTransactionManager();         return new JtaTransactionManager(userTransaction, atomikosTransactionManager);     }  } 

(CustomerConfig.java)

import java.util.Properties;  import javax.sql.DataSource;  import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement;  import com.atomikos.jdbc.AtomikosDataSourceBean; import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;  @Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages = "com.at.mul.repository.customer", entityManagerFactoryRef = "customerEntityManager", transactionManagerRef = "transactionManager") public class CustomerConfig {      @Autowired     private JpaVendorAdapter jpaVendorAdapter;      @Bean(name = "customerDataSource", initMethod = "init", destroyMethod = "close")     public DataSource customerDataSource() {         MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();         mysqlXaDataSource.setUrl("jdbc:mysql://localhost:3306/atomikos_1");         mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);         mysqlXaDataSource.setPassword("password");         mysqlXaDataSource.setUser("root");         mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);          AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();         xaDataSource.setXaDataSource(mysqlXaDataSource);         xaDataSource.setUniqueResourceName("xads1");         return xaDataSource;     }       @Bean(name = "customerEntityManager")     public LocalContainerEntityManagerFactoryBean customerEntityManager() throws Throwable {         LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();         entityManager.setDataSource(customerDataSource());         entityManager.setJpaVendorAdapter(jpaVendorAdapter);         entityManager.setPackagesToScan("com.at.mul.domain.customer");         entityManager.setPersistenceUnitName("customerPersistenceUnit");         Properties properties = new Properties();         properties.put("javax.persistence.transactionType", "JTA");         entityManager.setJpaProperties(properties);         return entityManager;     }  } 

(OrderConfig.java)

import java.util.Properties;  import javax.sql.DataSource;  import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement;  import com.atomikos.jdbc.AtomikosDataSourceBean; import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;  @Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages = "com.at.mul.repository.order", entityManagerFactoryRef = "orderEntityManager", transactionManagerRef = "transactionManager") public class OrderConfig {      @Autowired     private JpaVendorAdapter jpaVendorAdapter;      @Bean(name = "orderDataSource", initMethod = "init", destroyMethod = "close")     public DataSource orderDataSource() {         MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();         mysqlXaDataSource.setUrl("jdbc:mysql://localhost:3306/atomikos_2");         mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);         mysqlXaDataSource.setPassword("password");         mysqlXaDataSource.setUser("root");         mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);          AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();         xaDataSource.setXaDataSource(mysqlXaDataSource);         xaDataSource.setUniqueResourceName("xads2");         return xaDataSource;     }       @Bean(name = "orderEntityManager")     public LocalContainerEntityManagerFactoryBean orderEntityManager() throws Throwable {         LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();         entityManager.setDataSource(orderDataSource());         entityManager.setJpaVendorAdapter(jpaVendorAdapter);         entityManager.setPackagesToScan("com.at.mul.domain.order");         entityManager.setPersistenceUnitName("orderPersistenceUnit");         Properties properties = new Properties();         properties.put("javax.persistence.transactionType", "JTA");         entityManager.setJpaProperties(properties);         return entityManager;     }  } 

(CustomerRepository.java)

import org.springframework.data.jpa.repository.JpaRepository;  import com.at.mul.domain.customer.Customer;  public interface CustomerRepository extends JpaRepository<Customer, Integer> {  } 

(OrderRepository.java)

import org.springframework.data.jpa.repository.JpaRepository;  import com.at.mul.domain.order.Order;  public interface OrderRepository extends JpaRepository<Order, Integer> {  } 

I get a NullPointerException on when running this test:

import javax.transaction.Transactional;  import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  import com.at.mul.MainConfig; import com.at.mul.domain.customer.Customer; import com.at.mul.repository.customer.CustomerRepository;  @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MainConfig.class) @Transactional public class CustomerRepositoryTest {      @Autowired     private CustomerRepository customerRepository;      @Test     public void testCustomerConfig() {      }      @Test     public void save() {         Customer c = new Customer();         c.setName("test-name");         c.setAge(30);         Customer cust = customerRepository.save(c);         Assert.assertNotNull(cust.getId());     }  } 

The null object seems to be the transactionManager, so I suppose it's not properly injected. Relevant part of the stacktrace is here:

java.lang.NullPointerException     at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus(JtaStatusHelper.java:76)     at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.isActive(JtaStatusHelper.java:118)     at org.hibernate.engine.transaction.internal.jta.CMTTransaction.join(CMTTransaction.java:149)     at org.hibernate.jpa.spi.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:1602)     at org.hibernate.jpa.spi.AbstractEntityManagerImpl.postInit(AbstractEntityManagerImpl.java:210)     at org.hibernate.jpa.internal.EntityManagerImpl.<init>(EntityManagerImpl.java:91)     at org.hibernate.jpa.internal.EntityManagerFactoryImpl.internalCreateEntityManager(EntityManagerFactoryImpl.java:345)     at org.hibernate.jpa.internal.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:313)     at sun.reflect.GeneratedMethodAccessor10.invoke(Unknown Source)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)     at java.lang.reflect.Method.invoke(Method.java:597)     at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:388)     at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:541)     at com.sun.proxy.$Proxy29.createEntityManager(Unknown Source)     at org.springframework.orm.jpa.EntityManagerFactoryUtils.doGetTransactionalEntityManager(EntityManagerFactoryUtils.java:285)     at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:227)     at com.sun.proxy.$Proxy34.persist(Unknown Source)     at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:369) 

The pom file is here:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">     <modelVersion>4.0.0</modelVersion>      <parent>         <groupId>org.springframework.boot</groupId>         <artifactId>spring-boot-starter-parent</artifactId>         <version>1.0.0.RC5</version>     </parent>      <groupId>com.at.mul</groupId>     <artifactId>mul-at</artifactId>     <version>1.0-SNAPSHOT</version>     <packaging>jar</packaging>      <name>mul-at</name>     <url>http://maven.apache.org</url>      <properties>         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>     </properties>      <build>         <plugins>             <plugin>                 <groupId>org.springframework.boot</groupId>                 <artifactId>spring-boot-maven-plugin</artifactId>             </plugin>         </plugins>     </build>      <repositories>         <repository>             <id>spring-snapshots</id>             <url>http://repo.spring.io/libs-snapshot</url>             <snapshots>                 <enabled>true</enabled>             </snapshots>         </repository>     </repositories>      <pluginRepositories>         <pluginRepository>             <id>spring-snapshots</id>             <url>http://repo.spring.io/libs-snapshot</url>             <snapshots>                 <enabled>true</enabled>             </snapshots>         </pluginRepository>     </pluginRepositories>      <dependencies>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-data-jpa</artifactId>         </dependency>          <dependency>             <groupId>mysql</groupId>             <artifactId>mysql-connector-java</artifactId>         </dependency>          <dependency>             <groupId>org.projectlombok</groupId>             <artifactId>lombok</artifactId>             <version>1.12.4</version>         </dependency>          <dependency>             <groupId>com.atomikos</groupId>             <artifactId>transactions</artifactId>             <version>3.9.3</version>         </dependency>          <dependency>             <groupId>com.atomikos</groupId>             <artifactId>transactions-jta</artifactId>             <version>3.9.3</version>         </dependency>          <dependency>             <groupId>com.atomikos</groupId>             <artifactId>transactions-hibernate3</artifactId>             <version>3.9.3</version>             <exclusions>                 <exclusion>                     <artifactId>hibernate</artifactId>                     <groupId>org.hibernate</groupId>                 </exclusion>             </exclusions>         </dependency>           <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-test</artifactId>         </dependency>          <dependency>             <groupId>junit</groupId>             <artifactId>junit</artifactId>             <scope>test</scope>         </dependency>     </dependencies> </project> 

Full code is available on Github: https://github.com/fabiomaffioletti/mul-at I could not find any working example, and even after looking at the Spring blog article I cannot get it to work. Has anyone any hint?

Following the console log of spring boot for the customer connection:

2014-04-01 11:29:48.645  INFO 22368 --- [           main] c.atomikos.jdbc.AbstractDataSourceBean   : AtomikosDataSoureBean 'xads1': init... 2014-04-01 11:29:48.645  WARN 22368 --- [           main] c.atomikos.jdbc.AbstractDataSourceBean   : AtomikosDataSoureBean 'xads1': poolSize equals default - this may cause performance problems! 2014-04-01 11:29:48.672  INFO 22368 --- [           main] c.atomikos.jdbc.AtomikosDataSourceBean   : AtomikosDataSoureBean 'xads1': initializing with [ xaDataSourceClassName=null, uniqueResourceName=xads1, maxPoolSize=1, minPoolSize=1, borrowConnectionTimeout=30, maxIdleTime=60, reapTimeout=0, maintenanceInterval=60, testQuery=null, xaProperties=[], loginTimeout=0, maxLifetime=0] 2014-04-01 11:29:48.809  INFO 22368 --- [           main] c.a.icatch.imp.thread.TaskManager        : THREADS: using JDK thread pooling... 2014-04-01 11:29:48.837  INFO 22368 --- [           main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'customerPersistenceUnit' 2014-04-01 11:29:48.857  INFO 22368 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [     name: customerPersistenceUnit     ...] 2014-04-01 11:29:48.919  INFO 22368 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {4.3.1.Final} 2014-04-01 11:29:48.920  INFO 22368 --- [           main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found 2014-04-01 11:29:48.922  INFO 22368 --- [           main] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist 2014-04-01 11:29:49.057  INFO 22368 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {4.0.4.Final} 2014-04-01 11:29:49.086  INFO 22368 --- [           main] c.atomikos.jdbc.AbstractDataSourceBean   : AtomikosDataSoureBean 'xads1': getConnection ( null )... 2014-04-01 11:29:49.087  INFO 22368 --- [           main] c.atomikos.jdbc.AbstractDataSourceBean   : AtomikosDataSoureBean 'xads1': init... 2014-04-01 11:29:49.145  WARN 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: WARNING: transaction manager not running? 2014-04-01 11:29:49.145  INFO 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: calling getMetaData... 2014-04-01 11:29:49.166  INFO 22368 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect 2014-04-01 11:29:49.172  WARN 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: WARNING: transaction manager not running? 2014-04-01 11:29:49.172  INFO 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: calling getCatalog... 2014-04-01 11:29:49.174  WARN 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: WARNING: transaction manager not running? 2014-04-01 11:29:49.175  INFO 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: calling getMetaData... 2014-04-01 11:29:49.175  WARN 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: WARNING: transaction manager not running? 2014-04-01 11:29:49.175  INFO 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: calling createClob... 2014-04-01 11:29:49.177  WARN 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: WARNING: transaction manager not running? 2014-04-01 11:29:49.177  INFO 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: close()... 2014-04-01 11:29:49.258  INFO 22368 --- [           main] o.h.h.i.ast.ASTQueryTranslatorFactory    : HHH000397: Using ASTQueryTranslatorFactory 2014-04-01 11:29:49.428  INFO 22368 --- [           main] org.hibernate.tool.hbm2ddl.SchemaUpdate  : HHH000228: Running hbm2ddl schema update 2014-04-01 11:29:49.428  INFO 22368 --- [           main] org.hibernate.tool.hbm2ddl.SchemaUpdate  : HHH000102: Fetching database metadata 2014-04-01 11:29:49.428  INFO 22368 --- [           main] c.atomikos.jdbc.AbstractDataSourceBean   : AtomikosDataSoureBean 'xads1': getConnection ( null )... 2014-04-01 11:29:49.428  INFO 22368 --- [           main] c.atomikos.jdbc.AbstractDataSourceBean   : AtomikosDataSoureBean 'xads1': init... 2014-04-01 11:29:49.428  WARN 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: WARNING: transaction manager not running? 2014-04-01 11:29:49.428  INFO 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: calling getAutoCommit... 2014-04-01 11:29:49.429  WARN 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: WARNING: transaction manager not running? 2014-04-01 11:29:49.429  INFO 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: calling getMetaData... 2014-04-01 11:29:49.429  WARN 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: WARNING: transaction manager not running? 2014-04-01 11:29:49.430  WARN 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: WARNING: transaction manager not running? 2014-04-01 11:29:49.430  INFO 22368 --- [           main] c.atomikos.jdbc.AtomikosConnectionProxy  : atomikos connection proxy for com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@63f9f0f2: calling createStatement... 2014-04-01 11:29:49.431  INFO 22368 --- [           main] org.hibernate.tool.hbm2ddl.SchemaUpdate  : HHH000396: Updating schema 2014-04-01 11:29:49.446  INFO 22368 --- [           main] o.hibernate.tool.hbm2ddl.TableMetadata   : HHH000261: Table found: atomikos_1.customer 2014-04-01 11:29:49.446  INFO 22368 --- [           main] o.hibernate.tool.hbm2ddl.TableMetadata   : HHH000037: Columns: [id, age, name] 2014-04-01 11:29:49.446  INFO 22368 --- [           main] o.hibernate.tool.hbm2ddl.TableMetadata   : HHH000108: Foreign keys: [] 2014-04-01 11:29:49.446  INFO 22368 --- [           main] o.hibernate.tool.hbm2ddl.TableMetadata   : HHH000126: Indexes: [primary] 2014-04-01 11:29:49.447  INFO 22368 --- [           main] org.hibernate.tool.hbm2ddl.SchemaUpdate  : HHH000232: Schema update complete 

回答1:

I think the CMTTransaction in the stack trace is the clue: Hibernate thinks you are in a container. I also think it might work if you just remove the javax.persistence.transactionType=JTA property.



回答2:

Ofcource, you can remove javax.persistence.transactionType=JTA and it will work.

But if you want to use JBOSS AS with own transaction manager (i like it more; there is a some bugs in atomicos which has fixed only customer version), you must put:

transactionType=JTA 

Into persistance.xml property:

<property name="hibernate.transaction.jta.platform"                       value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" /> 

Into spring-config:

<tx:jta-transaction-manager/> <tx:annotation-driven/> 


回答3:

https://blog.hanqunfeng.com/2016/12/21/spring-boot-study-jpa/#more

@Bean(name = "entityManagerFactory") @DependsOn({"atomikosJtaPlatfom"}) //需要先注册atomikosJtaPlatfom public LocalContainerEntityManagerFactoryBean entityManagerFactory() { System.out.println("entityManagerFactory init"); LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean(); entityManager.setJpaVendorAdapter(jpaVendorAdapter()); // entity package entityManager.setPackagesToScan("com.example.model.ds1"); entityManager.setJtaDataSource(dataSource()); Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"); properties.put("hibernate.show_sql", "true"); properties.put("hibernate.format_sql", "true"); //jta设置 properties.put("hibernate.current_session_context_class", "jta"); properties.put("hibernate.transaction.factory_class", "org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory"); //这里指定我们自己创建的AtomikosJtaPlatfom properties.put("hibernate.transaction.jta.platform","com.example.AtomikosJtaPlatfom"); entityManager.setJpaProperties(properties); return entityManager; }



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!