gpt4 book ai didi

java - Hibernate 4(使用 Atomikos 事务管理器的 Jpa 2.0 + Jta)未将对象保存在 mysql 模式中

转载 作者:行者123 更新时间:2023-11-30 11:31:37 25 4
gpt4 key购买 nike

我正在阅读 Pro Spring 3 这本书,在有关全局事务的章节中,有一些示例代码用于将一个对象保存到两个不同的 mysql 模式中。我正在运行代码,但对象未保存在两个模式中的任何一个中。这是代码。

tx-jta-app-context.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

<context:annotation-config />
<context:component-scan base-package="foo.bar.service.jta"/>

<bean id="dataSourceA" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<property name="uniqueResourceName">
<value>XADBMSA</value>
</property>
<property name="xaDataSourceClassName">
<value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value>
</property>
<property name="xaProperties">
<props>
<prop key="databaseName">prospring3_ch13a</prop>
<prop key="user">prospring3_ch13a</prop>
<prop key="password">prospring3_ch13a</prop>
</props>
</property>
<property name="poolSize">
<value>1</value>
</property>
</bean>
<bean id="dataSourceB" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<property name="uniqueResourceName">
<value>XADBMSB</value>
</property>
<property name="xaDataSourceClassName">
<value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value>
</property>
<property name="xaProperties">
<props>
<prop key="databaseName">prospring3_ch13b</prop>
<prop key="user">prospring3_ch13b</prop>
<prop key="password">prospring3_ch13b</prop>
</props>
</property>
<property name="poolSize">
<value>1</value>
</property>
</bean>

<!-- Construct Atomikos UserTransactionManager, needed to configure Spring -->
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
<!-- when close is called, should we force transactions to terminate or not? -->
<property name="forceShutdown">
<value>true</value>
</property>
</bean>

<!-- Also use Atomikos UserTransactionImp, needed to configure Spring -->
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout">
<value>300</value>
</property>
</bean>

<!-- Configure the Spring framework to use JTA transactions from Atomikos -->
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager">
<ref bean="atomikosTransactionManager"/>
</property>
<property name="userTransaction">
<ref bean="atomikosUserTransaction"/>
</property>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="emfBase" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" abstract="true">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="packagesToScan" value="foo.bar.domain"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.transaction.factory_class">
${com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory}
</prop>
<prop key="hibernate.transaction.manager_lookup_class">
${com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup}
</prop>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQL5Dialect
</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>

<bean id="emfA" parent="emfBase">
<property name="dataSource" ref="dataSourceA"/>
</bean>

<bean id="emfB" parent="emfBase">
<property name="dataSource" ref="dataSourceB"/>
</bean>
</beans>

foo/bar/service/jta/ContactServiceImpl.java :

package foo.bar.service.jta;

import foo.bar.domain.Contact;
import foo.bar.service.ContactService;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;


@Service("contactService")
@Repository
@Transactional
public class ContactServiceImpl implements ContactService{

@PersistenceContext(unitName = "emfA")
private EntityManager emA;

@PersistenceContext(unitName = "emfB")
private EntityManager emB;

@Override
@Transactional(readOnly = true)
public List<Contact> findAll() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}

@Override
@Transactional(readOnly = true)
public Contact findById(Long id) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}

@Override
public Contact save(Contact contact) {
Contact contactB = new Contact();
contactB.setFirstName(contact.getFirstName());
contactB.setLastName(contact.getLastName());
if (contact.getId() == null)
{
emA.persist(contact);
emB.persist(contactB);
//throw new JpaSystemException(new PersistenceException());
}
else
{
emA.merge(contact);
emB.merge(contact);
}

return contact;
}

@Override
public long countAll() {
return 0; //To change body of implemented methods use File | Settings | File Templates.
}
}

foo/bar/domain/Contact.java:

package foo.bar.domain;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

import static javax.persistence.GenerationType.IDENTITY;

@Entity
@Table(name = "contact")
@NamedQueries({
@NamedQuery(name = "Contact.findAll", query="select c from Contact c"),
@NamedQuery(name = "Contact.countAll", query="select count(c) from Contact c")
})
public class Contact implements Serializable{

private Long id;
private int version;
private String firstName;
private String lastName;
private Date birthDate;

public Contact()
{

}

//getters and setters
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "ID")
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

@Version
@Column(name = "VERSION")
public int getVersion() {
return version;
}

public void setVersion(int version) {
this.version = version;
}

@Column(name = "FIRST_NAME")
public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

@Column(name = "LAST_NAME")
public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

@Temporal(TemporalType.DATE)
@Column(name = "BIRTH_DATE")
public Date getBirthDate() {
return birthDate;
}

public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}

//other methods
public String toString()
{
return "Contact - Id: " + id + ", First name: " + firstName + ", Last name: " + lastName + ", Birthday: " + birthDate;
}
}

foo/bar/TxJtaSample.java:

package foo.bar;

import foo.bar.domain.Contact;
import foo.bar.service.ContactService;
import org.springframework.context.support.GenericXmlApplicationContext;


public class TxJtaSample {

public static void main(String[] args) {
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("tx-jta-app-context.xml");

ContactService contactService = ctx.getBean("contactService", ContactService.class);

Contact contact = new Contact();
contact.setFirstName("Jta");
contact.setLastName("Manager");
contactService.save(contact);

System.out.println("Contact saved successfully");
}
}

pom.xml:

<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>foo.bar</groupId>
<artifactId>SimpleProject26</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>SimpleProject26</name>
<url>http://maven.apache.org</url>

<properties>
<spring.version>3.2.3.RELEASE</spring.version>
<aspectj.version>1.7.2</aspectj.version>
</properties>

<dependencies>
<!-- Core Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>

<!-- Spring Data -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.3.2.RELEASE</version>
</dependency>

<!-- Commons Dbcp Driver -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>

<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.2.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.0.1.Final</version>
</dependency>

<!-- MySql Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>

<!-- JUnit testing framework -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>

<!-- Logging -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.2</version>
</dependency>

<!-- Javax validation -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>

<!-- Joda time for Hibernate 4 -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time-hibernate</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.jadira.usertype</groupId>
<artifactId>usertype.core</artifactId>
<version>3.1.0.CR6</version>
</dependency>

<!-- Google Guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>14.0.1</version>
</dependency>

<!-- AspectJ Framework -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>

<!-- Atomikos Transaction Framework -->
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jdbc</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-hibernate3</artifactId>
<version>3.8.0</version>
</dependency>

</dependencies>

<build>
<finalName>SpringApp</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/*Tests.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</project>

我在控制台上得到的输出如下:

http://pastebin.com/VV8ukbwy

最佳答案

测试您的代码后,我进行了 3 处修改,所有修改都在 tx-jta-app-context.xml 中配置文件,在emfBase的声明中 bean :

  1. 我删除了 key hibernate.transaction.factory_class ,如 this page 中所述,当您使用 JPA 时。
  2. 我删除了 com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup 类周围的 ${...} (也许您在项目中定义了一个变量,但如果没有,则应删除它们)。
  3. 我向 jpaProperties 添加了一个属性:<prop key="javax.persistence.transactionType">jta</prop> . @Jukka 在他的评论中告诉您查看文档,最后,他们说要添加此属性并且它适用于他们。

经过这些修改后,它对我有用(我可以更新 2 个数据库,如果我在事务期间生成错误,则回滚在两个数据库中正确执行)。我在这里为您提供 emfBase 的最终定义 bean :

    <bean id="emfBase" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" abstract="true">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="packagesToScan" value="foo.bar.domain"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.transaction.manager_lookup_class">
com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup
</prop>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQL5Dialect
</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="javax.persistence.transactionType">jta</prop>
</props>
</property>
</bean>

希望能解决您的问题。

关于java - Hibernate 4(使用 Atomikos 事务管理器的 Jpa 2.0 + Jta)未将对象保存在 mysql 模式中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17073281/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com