`
koen
  • 浏览: 80799 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

使用JPA的EntityManager.persist()无法保存到数据库的问题

阅读更多

 

我这两天刚开始使用JPA,遇到了一个问题,现象是这样的:使用EntityManager查询对象没有问题,但是持久化对象时,也就是使用entityMananger.persist()时,没有保存到数据库,此时程序没有也没有任何异常抛出。

 

忙了一天也没有搜索到解决方法,第二天和同事讨论,再次进行各种尝试,包括在persist前后加入transaction控制,如下:

 

entityManager.getTransaction().begin();
entityManager.persist(it);
entityManager.getTransaction().commit();

 

此时得到一个IllegalStateException: “A JTA EntityManager cannot use getTransaction()”.

 

Google以上异常描述,得到以下Hibernate的源代码页面:

 

http://viewvc.jboss.org/cgi-bin/viewvc.cgi/hibernate/branches/Branch_3_2/HibernateExt/entitymanager/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java?view=markup&pathrev=11268

 

其中有一段代码是关于该异常的:

 

public EntityTransaction getTransaction() {
		if ( transactionType == PersistenceUnitTransactionType.JTA ) {
			throw new IllegalStateException( "A JTA EntityManager cannot use getTransaction()" );
		}
		return tx;
	}

 

看到“transactionType”字样,灵机一动,联想到在persistence.xml中有以下配置:

 

<persistence-unit name="IncidentTicketServicePU" transaction-type="JTA">

 

这时我想到这里的“transaction-type”可能需要设成其他值。搜索persistence.xml的schema定义“http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd”,在其中发现如下内容:

 

<xsd:simpleType name="persistence-unit-transaction-type">
  <xsd:annotation>
    <xsd:documentation>public enum TransactionType { JTA, RESOURCE_LOCAL };</xsd:documentation> 
  </xsd:annotation>
  <xsd:restriction base="xsd:token">
    <xsd:enumeration value="JTA" /> 
    <xsd:enumeration value="RESOURCE_LOCAL" /> 
  </xsd:restriction>
</xsd:simpleType>

 

当然,这时把persistence.xml中的“transaction-type”改成"RESOURCE_LOCAL",如下:

 

<persistence-unit name="IncidentTicketServicePU" transaction-type="RESOURCE_LOCAL">

 

再跑,数据成功插入数据库。

 

 

经过思考,我觉得问题的原因是这样的:首先,

在我的代码中使用了以下代码获得EntityManager实例:

 

EntityManagerFactory emf = 
Persistence.createEntityManagerFactory("IncidentTicketServicePU");
EntityManager em = emf.createEntityManager();

 
之所以使用这种方式而没有使用@PersistenceContext注入EntityManager,是因为当时使用注入方式不成功。今天得知在POJO上是无法使用@PersistenceContext注入的,只能在ejb上使用,这就是为什么之前我使用注入失败的原因。


再回到原来的问题,用工厂方式获得EntityManager发生错误的原因是:用工厂方式获得的EntityManager的transaction实际上应该由应用程序自己管理,而非JTA管理。但是由于设置了transaction-type="JTA",实际上并没有任何代码负责对transaction的管理,而且在代码中手工管理transaction还会报错。要解决这个问题有两种方法:


1. 按照我上面描述的方法修改persistence.xml中的“transaction-type”并编写手工管理transaction的代码;

 

2. 不修改transaction-type="JTA",使用session bean,在session bean中使用@PersistenceContext注入EntityManager。这样在程序里不用自己控制transaction,直接persist就可以。


两种方式都可以正常运行,但是为了是代码的优雅,最终选择了第二种方法。

 

 

5
0
分享到:
评论
3 楼 k1280000 2012-08-27  
建议你看看这篇文字 http://wenku.baidu.com/view/34332f6327d3240c8447ef48.html
2 楼 sxitzmg 2011-12-16  
感谢啊,困扰我48小数的bug解决了
1 楼 prosper 2010-03-24  
我也遇到了这样的问题。(Spring MVC 2 + JPA,  MySQL + Tomcat 6, )

我需要在JUnit里,手动读配置Spring文件,并获得DAO, Service的实例,然后测试
增删改等等操作。

我在里没有定义任何transaction-type,

只是陈列了要储存的类:     <persistence-unit name="punit">
<!-- provider>org.hibernate.ejb.HibernatePersistence</provider -->
   
<class>com.my.jpa.model.Customer</class>

我不能用EJB因为容器是Tomcat。但是我这样写出来的DAO只能在Web app
里运行,到了 JUNIT里就发生 javax.persistence.RollbackException: Transaction marked as rollbackOnly.
请问楼主应该怎么办?


在DAO里:

@Repository("customerDao")
class CustomerDAO{
@PersistenceContext
private EntityManager em;
...
}


在Service里:

@Service("customerService")
@Transactional
class CustomerService{
@Autowired
private CustomerDAO customerDao;

}

在Spring config file里:   

    <bean id="transactionManager"
        class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager" />   
    <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<!-- persistence -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />



相关推荐

    个人博客系统(SpringBoot+jpa).zip

    个人博客系统(SpringBoot+jpa).zip个人博客系统(SpringBoot+jpa).zip个人博客系统(SpringBoot+jpa).zip个人博客系统(SpringBoot+jpa).zip个人博客系统(SpringBoot+jpa).zip个人博客系统(SpringBoot+jpa)...

    JPA注解.doc J PA注解.

    JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解.doc JPA注解....

    Spring Data JPA原理.pptx

    Spring Data JPA原理.pptx

    jpa--7.api(EntityManager其他方法)

    jpa--7.api(EntityManager其他方法)jpa--7.api(EntityManager其他方法)jpa--7.api(EntityManager其他方法)jpa--7.api(EntityManager其他方法)

    Struts2.1+Spring3.0+JPA1.0 .pdf

    Struts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdfStruts2.1+Spring3.0+JPA1.0 .pdf

    JPA注解参考文档.txt

    段持久保存到.系.据.(在 Java EE EJB容器的.部或在.. Java SE .用程序中的 EJB 容器的外部) 的 Java .象。 使用 JPA .,可以使用批注配置.体的 JPA 行.。批注是一种使用元.据修. Java 源代.的..表. 方法,它......

    spring4 mvc + jpa demo

    pom.xml 的引入的相关jar版本配置 ... &lt;hibernate-entitymanager.version&gt;4.1.0.Final&lt;/hibernate-entitymanager.version&gt; &lt;hibernate-jpa.version&gt;1.0.1.Final&lt;/hibernate-jpa.version&gt; &lt;/properties&gt;

    仓库管理系统,SpringBoot+Spring Data JPA+......zip

    仓库管理系统,SpringBoot+Spring Data JPA+.....

    05_JPA详解_日期_枚举等字段类型的JPA映射.zip

    05_JPA详解_日期_枚举等字段类型的JPA映射.zip 05_JPA详解_日期_枚举等字段类型的JPA映射.zip

    管理系统系列--仓库管理系统,SpringBoot+Spring Data JPA+......zip

    管理系统系列--仓库管理系统,SpringBoot+Spring Data JPA+.....

    TutorialsPoint JPA 教程.epub

    TutorialsPoint JPA 教程.epub

    第十三章 开发JPA应用.pdf

    MyEclipse 6 Java 开发中文教程2011.pdfMyEclipse 6 Java 开发中文教程2011.pdfMyEclipse 6 Java 开发中文教程2011....开发JPA应用.pdf第十三章 开发JPA应用.pdf第十三章 开发JPA应用.pdf第十三章 开发JPA应用.pdf

    使用SpringBoot-JPA进行自定义保存及批量保存功能

    主要介绍了使用SpringBoot-JPA进行自定义的保存及批量保存功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

    仓库管理系统,SpringBoot+Spring Data JPA.zip

    仓库管理系统,SpringBoot+Spring Data JPA.zip仓库管理系统,SpringBoot+Spring Data JPA.zip仓库管理系统,SpringBoot+Spring Data JPA.zip仓库管理系统,SpringBoot+Spring Data JPA.zip仓库管理系统,SpringBoot...

    Spring Data JPA.rar

    使用Spring Boot 2.1.6轻松实现JPA操作MySQL数据库的CRUD,以及分页和排序功能。在Spring Boot 2.x版本中可以非常轻松、快速搞定持久层的开发动作,配置比SpringBoot+MyBatis还少,偶觉得它除了执行效果不如...

    spring-data-jpa-2.0.9.RELEASE-API文档-中文版.zip

    赠送jar包:spring-data-jpa-2.0.9.RELEASE.jar; 赠送原API文档:spring-data-jpa-2.0.9.RELEASE-javadoc.jar; 赠送源代码:spring-data-jpa-2.0.9.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-data-jpa...

    JavaWeb大作业基于springboot+JPA的网络点餐系统源码+数据库.zip

    JavaWeb大作业基于springboot+JPA的网络点餐系统源码+数据库.zipJavaWeb大作业基于springboot+JPA的网络点餐系统源码+数据库.zipJavaWeb大作业基于springboot+JPA的网络点餐系统源码+数据库.zipJavaWeb大作业基于...

Global site tag (gtag.js) - Google Analytics