2012-05-22 54 views
0

我正在研究一个小的Spring-Hibernate-Mysql测试项目,并且由于某种原因,我的事务没有被提交给数据库。JPA事务没有提交给DB

在我的应用上下文我:

<!-- JTA --> 

<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 

</bean> 

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

<!-- JPA --> 

<jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/myPU" /> 

<!-- In order to enable EntityManager injection --> 
<bean 
    class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"> 
    <property name="persistenceUnits"> 
     <map> 
      <entry key="myPU" value="persistence/myPU" /> 
     </map> 
    </property> 
</bean> 

我的persistence.xml:

<persistence-unit name="myPU" transaction-type="JTA"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 
    <jta-data-source>jdbc/mysqlResource</jta-data-source> 
    <properties> 
     <property name="hibernate.connection.shutdown" value="true" /> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"></property> 
     <property name="hibernate.show_sql" value="true" /> 
    </properties> 
</persistence-unit> 

我创建了一个名为 '人' 在我的分贝简单的表:

CREATE TABLE persons(
id VARCHAR(255) PRIMARY KEY, 
version int, 
full_name VARCHAR(255), 
person_id VARCHAR(255), 
email VARCHAR(255)); 

创建实体一个相应的实体和道:

@Entity 
@Table(name = "persons") 
public class Person implements Serializable { 

private static final long serialVersionUID = 4349832844316517922L; 

/*--- Members ---*/ 

/** 
* Hibernate genetared UUID 
*/ 
@Id 
@GeneratedValue(generator = "system-uuid") 
@GenericGenerator(name = "system-uuid", strategy = "uuid") 
private String id; 

@Version 
private int version; 

@Column(name = "full_name") 
private String fullName; 

@Column(name = "person_id") 
private String personId; 

@Column(name = "email") 
private String eMail; 

/*--- Constructor ---*/ 

public Person() { 
} 

/*--- Overridden Methods ---*/ 

@Override 
public boolean equals(Object obj) { 

    if ((obj == null) || !(obj instanceof Person)) { 
     return false; 
    } 

    // reference comparison 
    if (obj == this) { 
     return true; 
    } 

    final Person other = (Person) obj; 

    return new EqualsBuilder().append(getPersonId(), other.getPersonId()) 
      .append(geteMail(), other.geteMail()) 
      .append(getFullName(), other.getFullName()).isEquals(); 
} 

/** 
* The unique hash code based on the clients' id and citizenship 
* 
* {@inheritDoc} 
*/ 
@Override 
public int hashCode() { 

    return new HashCodeBuilder().append(geteMail()).append(this.geteMail()) 
      .append(this.getFullName()).toHashCode(); 
} 

/*--- Getters & Setters ---*/ 

public String getId() { 
    return id; 
} 

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

public int getVersion() { 
    return version; 
} 

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

public String getFullName() { 
    return fullName; 
} 

public void setFullName(String fullName) { 
    this.fullName = fullName; 
} 

public String getPersonId() { 
    return personId; 
} 

public void setPersonId(String personId) { 
    this.personId = personId; 
} 

public String geteMail() { 
    return eMail; 
} 

public void seteMail(String eMail) { 
    this.eMail = eMail; 
} 

}

道:

@Repository 
public class PersonJpaDao extends BasicJpaDao<Person> implements IPersonDao { 

public PersonJpaDao() { 
    super(Person.class); 
} 

}

这里是BasicJpaDao:

public class BasicJpaDao<T> implements IBasicDao<T> { 

/* --- Members --- */ 

/** The JPA utility to work with the persistence layer. */ 
@PersistenceContext 
protected EntityManager entityManager; 

/** The type of the entity to which this DAO offers access. */ 
protected Class<T> entityClass; 

/* --- Constructors --- */ 

/** 
* Default constructor. 
* 
* @param entityClass 
*   The type of the entity to which this DAO offers access. 
*/ 
public BasicJpaDao(Class<T> entityClass) { 
    super(); 
    this.entityClass = entityClass; 
} 

/* --- Public methods --- */ 

/** 
* {@inheritDoc} 
*/ 
@Override 
public void create(T entity) { 
    getEntityManager().persist(entity); 
} 

/** 
* {@inheritDoc} 
*/ 
@Override 
public T read(Object primaryKey) { 
    return getEntityManager().find(getEntityClass(), primaryKey); 
} 

/** 
* {@inheritDoc} 
*/ 
@Override 
public T update(T entity) { 
    return getEntityManager().merge(entity); 
} 

/** 
* {@inheritDoc} 
*/ 
@Override 
public void delete(T entity) { 
    getEntityManager().remove(entity); 
} 

/** 
* {@inheritDoc} 
*/ 
@Override 
public void flush() { 
    getEntityManager().flush(); 
} 

/* --- Getters/Setters --- */ 

/** 
* @return The JPA utility to work with the persistence layer. 
*/ 
public EntityManager getEntityManager() { 
    return this.entityManager; 
} 

/** 
* @param entityManager 
*   The JPA utility to work with the persistence layer. 
*/ 
public void setEntityManager(EntityManager entityManager) { 
    this.entityManager = entityManager; 
} 

/** 
* @return The type of the entity to which this DAO offers access. 
*/ 
public Class<T> getEntityClass() { 
    return entityClass; 
} 

/** 
* @param entityClass 
*   The type of the entity to which this DAO offers access. 
*/ 
public void setEntityClass(Class<T> entityClass) { 
    this.entityClass = entityClass; 
} 

洙。基本上这工作,但没有被提交,我的意思是,如果我运行

@Transactional(propagation = Propagation.REQUIRED) 
private void crearePerson() { 
    Person p1 = myDao.read("12345"); 
    p1.setFullName("kiko too"); 
    myDao.update(p1); 
} 

我可以看到(在调试中)p1从数据库中取回,但更新从不发生。 我能找到的唯一的东西接近的是:

JPA - transactions not being committed

我尝试添加

​​

我的persistence.xml这个线程以下,但它并没有帮助。 我还向我的连接池(在我的应用程序服务器gui中)添加了一个属性,名为connection.shutdown,值为true,但它也没有帮助。

更新: 由于我使用JTA我想我的事务管理器是错误配置的。当我使用org.springframework.orm.jpa.JpaTransactionManager时,我应该使用org.springframework.transaction.jta.JtaTransactionManager。 所以我改变了我的应用程序上下文,我现在有:

<bean id="txManager" 
    class="org.springframework.transaction.jta.JtaTransactionManager" /> 

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

不幸的是,我仍然遇到了同样的问题:( 在我的控制台我可以看到Hibernate查询如下()我已经改变一些我原来的实体字段,但它并不重要):

INFO:Hibernate:select user0_.id as id0_0_,user0_.email as email0_0_,user0_.full_name as full3_0_0_,user0_.password as password0_0_,user0_ .update_by_email as update5_0_0_,user0_.user_name as user6_0_0_,user0_.version as version0_0_ from users user0_ where user0_.id =?

任何想法?

由于提前, 瑜珈

回答

1

添加 “@事务” 您create()方法。

编辑:这是更好的做法,把@Transactional在服务层,而不是DAO层仅供参考

+0

嗨,谢谢你。我在交易中运行,只是编辑了我的问题。仍然无法看到我的表在运行代码后得到更新,我确信同意 - @Transactional注释通常应该在业务逻辑层 – forhas

3

它可能不工作的原因是因为你是在一个私人的方法使用@Transactional@Transactional将不会对非公开方法产生影响,因为代理生成器会忽略它们。从Spring Documentation

方法的知名度和@Transactional

当使用代理服务器,你应该应用@Transactional注解 只与公众知名度的方法。如果使用@Transactional注释 注释受保护的 私有或包可见方法,则不会引发错误,但带注释的方法不会显示配置的事务设置 。如果您需要注释非公共方法,请考虑使用AspectJ(请参阅下面的 )。

+0

谢谢!但是改变方法可见性并没有帮助,而且,我认为由于我的类(包含crearePerson方法的类)实现了一个没有定义crearePerson方法的接口,因此spring将无法使用事务注释。所以,我尝试了两种不同的方法,第一种将方法声明添加到界面 - 仍然不起作用。其次,添加cglig并声明以使spring忽略该接口。这也没有帮助。我迷路了 – forhas

1

我有一个类似的问题,并为我修复从下面传来:

在PersistenceXML:

<property name="hibernate.transaction.manager_lookup_class" 
value="org.hibernate.transaction.JBossTransactionManagerLookup"> 

春文件:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="persistenceUnitName" value="nameOfUnitInPersistenceXml" /> 
</bean> 

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> 
    <property name="transactionManagerName" value="java:/TransactionManager" /> 
</bean> 

Java类(命名持久化上下文)

private EntityManager em; 

@PersistenceContext(name="nameOfUnitInPersistenceXml") 
public void setEntityManager(EntityManager em) { 
    this.em = em; 
} 
相关问题