fix jpa multiple db
This commit is contained in:
parent
fff145eb68
commit
3cc4fb96c1
|
@ -52,13 +52,6 @@
|
||||||
<version>1.6.0.RELEASE</version>
|
<version>1.6.0.RELEASE</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- atomikos -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.atomikos</groupId>
|
|
||||||
<artifactId>transactions-jta</artifactId>
|
|
||||||
<version>3.9.3</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- validation -->
|
<!-- validation -->
|
||||||
|
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
package org.baeldung.config;
|
|
||||||
|
|
||||||
import javax.transaction.TransactionManager;
|
|
||||||
import javax.transaction.UserTransaction;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
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.core.env.Environment;
|
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
|
||||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
|
||||||
|
|
||||||
import com.atomikos.icatch.jta.UserTransactionImp;
|
|
||||||
import com.atomikos.icatch.jta.UserTransactionManager;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@ComponentScan({ "org.baeldung.persistence.multiple" })
|
|
||||||
@EnableTransactionManagement
|
|
||||||
public class MultipleDBJPAConfig {
|
|
||||||
@Autowired
|
|
||||||
private Environment env;
|
|
||||||
|
|
||||||
public MultipleDBJPAConfig() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean(name = "userTransaction")
|
|
||||||
public UserTransaction userTransaction() {
|
|
||||||
final UserTransactionImp userTransactionImp = new UserTransactionImp();
|
|
||||||
return userTransactionImp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean(name = "atomikosTransactionManager")
|
|
||||||
public TransactionManager atomikosTransactionManager() {
|
|
||||||
final UserTransactionManager userTransactionManager = new UserTransactionManager();
|
|
||||||
MyJtaPlatform.transactionManager = userTransactionManager;
|
|
||||||
|
|
||||||
return userTransactionManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean(name = "transactionManager")
|
|
||||||
@DependsOn({ "userTransaction", "atomikosTransactionManager" })
|
|
||||||
public PlatformTransactionManager transactionManager() {
|
|
||||||
final UserTransaction userTransaction = userTransaction();
|
|
||||||
|
|
||||||
MyJtaPlatform.transaction = userTransaction;
|
|
||||||
|
|
||||||
final TransactionManager atomikosTransactionManager = atomikosTransactionManager();
|
|
||||||
return new JtaTransactionManager(userTransaction, atomikosTransactionManager);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package org.baeldung.config;
|
|
||||||
|
|
||||||
import javax.transaction.TransactionManager;
|
|
||||||
import javax.transaction.UserTransaction;
|
|
||||||
|
|
||||||
import org.hibernate.engine.transaction.jta.platform.internal.AbstractJtaPlatform;
|
|
||||||
|
|
||||||
public class MyJtaPlatform extends AbstractJtaPlatform {
|
|
||||||
|
|
||||||
public static TransactionManager transactionManager;
|
|
||||||
public static UserTransaction transaction;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected TransactionManager locateTransactionManager() {
|
|
||||||
return transactionManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected UserTransaction locateUserTransaction() {
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,14 +11,16 @@ import org.springframework.context.annotation.PropertySource;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||||
|
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@PropertySource({ "classpath:persistence-multiple-db.properties" })
|
@PropertySource({ "classpath:persistence-multiple-db.properties" })
|
||||||
@EnableJpaRepositories(basePackages = "org.baeldung.persistence.multiple.dao.product", entityManagerFactoryRef = "productEntityManager", transactionManagerRef = "transactionManager")
|
@EnableJpaRepositories(basePackages = "org.baeldung.persistence.multiple.dao.product", entityManagerFactoryRef = "productEntityManager", transactionManagerRef = "productTransactionManager")
|
||||||
public class ProductConfig {
|
public class ProductConfig {
|
||||||
@Autowired
|
@Autowired
|
||||||
private Environment env;
|
private Environment env;
|
||||||
|
@ -36,8 +38,6 @@ public class ProductConfig {
|
||||||
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||||
em.setJpaVendorAdapter(vendorAdapter);
|
em.setJpaVendorAdapter(vendorAdapter);
|
||||||
final HashMap<String, Object> properties = new HashMap<String, Object>();
|
final HashMap<String, Object> properties = new HashMap<String, Object>();
|
||||||
properties.put("hibernate.transaction.jta.platform", MyJtaPlatform.class.getName());
|
|
||||||
properties.put("javax.persistence.transactionType", "JTA");
|
|
||||||
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
|
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
|
||||||
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
|
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
|
||||||
em.setJpaPropertyMap(properties);
|
em.setJpaPropertyMap(properties);
|
||||||
|
@ -56,4 +56,11 @@ public class ProductConfig {
|
||||||
return dataSource;
|
return dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean(name = "productTransactionManager")
|
||||||
|
public PlatformTransactionManager transactionManager() {
|
||||||
|
final JpaTransactionManager transactionManager = new JpaTransactionManager();
|
||||||
|
transactionManager.setEntityManagerFactory(productEntityManagerFactory().getObject());
|
||||||
|
return transactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,18 +7,21 @@ import javax.sql.DataSource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.context.annotation.PropertySource;
|
import org.springframework.context.annotation.PropertySource;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||||
|
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@PropertySource({ "classpath:persistence-multiple-db.properties" })
|
@PropertySource({ "classpath:persistence-multiple-db.properties" })
|
||||||
@EnableJpaRepositories(basePackages = "org.baeldung.persistence.multiple.dao.user", entityManagerFactoryRef = "userEntityManager", transactionManagerRef = "transactionManager")
|
@EnableJpaRepositories(basePackages = "org.baeldung.persistence.multiple.dao.user", entityManagerFactoryRef = "userEntityManager", transactionManagerRef = "userTransactionManager")
|
||||||
public class UserConfig {
|
public class UserConfig {
|
||||||
@Autowired
|
@Autowired
|
||||||
private Environment env;
|
private Environment env;
|
||||||
|
@ -36,8 +39,6 @@ public class UserConfig {
|
||||||
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||||
em.setJpaVendorAdapter(vendorAdapter);
|
em.setJpaVendorAdapter(vendorAdapter);
|
||||||
final HashMap<String, Object> properties = new HashMap<String, Object>();
|
final HashMap<String, Object> properties = new HashMap<String, Object>();
|
||||||
properties.put("hibernate.transaction.jta.platform", MyJtaPlatform.class.getName());
|
|
||||||
properties.put("javax.persistence.transactionType", "JTA");
|
|
||||||
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
|
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
|
||||||
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
|
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
|
||||||
em.setJpaPropertyMap(properties);
|
em.setJpaPropertyMap(properties);
|
||||||
|
@ -56,4 +57,12 @@ public class UserConfig {
|
||||||
return dataSource;
|
return dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Primary
|
||||||
|
@Bean(name = "userTransactionManager")
|
||||||
|
public PlatformTransactionManager transactionManager() {
|
||||||
|
final JpaTransactionManager transactionManager = new JpaTransactionManager();
|
||||||
|
transactionManager.setEntityManagerFactory(userEntityManagerFactory().getObject());
|
||||||
|
return transactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,10 @@ package org.baeldung.persistence.multiple.model.product;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
|
@Table(schema = "spring_jpa_product")
|
||||||
public class Product {
|
public class Product {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
@ -41,4 +43,10 @@ public class Product {
|
||||||
this.price = price;
|
this.price = price;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("Product [name=").append(name).append(", id=").append(id).append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
package org.baeldung.persistence.multiple.model.user;
|
package org.baeldung.persistence.multiple.model.user;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.GenerationType;
|
import javax.persistence.GenerationType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
|
@Table(schema = "spring_jpa_user")
|
||||||
public class User {
|
public class User {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
@ -14,6 +17,7 @@ public class User {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
@Column(unique = true, nullable = false)
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
private int age;
|
private int age;
|
||||||
|
@ -54,4 +58,10 @@ public class User {
|
||||||
this.age = age;
|
this.age = age;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("User [name=").append(name).append(", id=").append(id).append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
# jdbc.X
|
||||||
|
jdbc.driverClassName=com.mysql.jdbc.Driver
|
||||||
|
user.jdbc.url=jdbc:mysql://localhost:3306/spring_jpa_user?createDatabaseIfNotExist=true
|
||||||
|
product.jdbc.url=jdbc:mysql://localhost:3306/spring_jpa_product?createDatabaseIfNotExist=true
|
||||||
|
jdbc.user=tutorialuser
|
||||||
|
jdbc.pass=tutorialmy5ql
|
||||||
|
|
||||||
|
# hibernate.X
|
||||||
|
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
|
||||||
|
hibernate.show_sql=false
|
||||||
|
hibernate.hbm2ddl.auto=create-drop
|
|
@ -1,8 +1,8 @@
|
||||||
package org.baeldung.persistence.service;
|
package org.baeldung.persistence.service;
|
||||||
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
import org.baeldung.config.MultipleDBJPAConfig;
|
|
||||||
import org.baeldung.config.ProductConfig;
|
import org.baeldung.config.ProductConfig;
|
||||||
import org.baeldung.config.UserConfig;
|
import org.baeldung.config.UserConfig;
|
||||||
import org.baeldung.persistence.multiple.dao.product.ProductRepository;
|
import org.baeldung.persistence.multiple.dao.product.ProductRepository;
|
||||||
|
@ -12,15 +12,15 @@ import org.baeldung.persistence.multiple.model.user.User;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.context.transaction.TransactionConfiguration;
|
import org.springframework.test.context.transaction.TransactionConfiguration;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration(classes = { MultipleDBJPAConfig.class, UserConfig.class, ProductConfig.class })
|
@ContextConfiguration(classes = { UserConfig.class, ProductConfig.class })
|
||||||
@Transactional
|
@TransactionConfiguration
|
||||||
@TransactionConfiguration(transactionManager = "transactionManager")
|
|
||||||
public class JPAMultipleDBTest {
|
public class JPAMultipleDBTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserRepository userRepository;
|
private UserRepository userRepository;
|
||||||
|
@ -29,9 +29,11 @@ public class JPAMultipleDBTest {
|
||||||
private ProductRepository productRepository;
|
private ProductRepository productRepository;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Transactional("userTransactionManager")
|
||||||
public void whenCreatingUser_thenCreated() {
|
public void whenCreatingUser_thenCreated() {
|
||||||
User user = new User();
|
User user = new User();
|
||||||
user.setName("John");
|
user.setName("John");
|
||||||
|
user.setEmail("john@test.com");
|
||||||
user.setAge(20);
|
user.setAge(20);
|
||||||
user = userRepository.save(user);
|
user = userRepository.save(user);
|
||||||
|
|
||||||
|
@ -39,6 +41,29 @@ public class JPAMultipleDBTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Transactional("userTransactionManager")
|
||||||
|
public void whenCreatingUsersWithSameEmail_thenRollback() {
|
||||||
|
User user1 = new User();
|
||||||
|
user1.setName("John");
|
||||||
|
user1.setEmail("john@test.com");
|
||||||
|
user1.setAge(20);
|
||||||
|
user1 = userRepository.save(user1);
|
||||||
|
assertNotNull(userRepository.findOne(user1.getId()));
|
||||||
|
|
||||||
|
User user2 = new User();
|
||||||
|
user2.setName("Tom");
|
||||||
|
user2.setEmail("john@test.com");
|
||||||
|
user2.setAge(10);
|
||||||
|
try {
|
||||||
|
user2 = userRepository.save(user2);
|
||||||
|
} catch (final DataIntegrityViolationException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNull(userRepository.findOne(user2.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional("productTransactionManager")
|
||||||
public void whenCreatingProduct_thenCreated() {
|
public void whenCreatingProduct_thenCreated() {
|
||||||
Product product = new Product();
|
Product product = new Product();
|
||||||
product.setName("Book");
|
product.setName("Book");
|
||||||
|
@ -48,4 +73,5 @@ public class JPAMultipleDBTest {
|
||||||
|
|
||||||
assertNotNull(productRepository.findOne(product.getId()));
|
assertNotNull(productRepository.findOne(product.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue