java - 在容器管理的实体管理器中获取 javax.persistence.TransactionRequiredException

标签 java jsf jpa java-ee-7

您好,我创建了一个简单的 JSF + JPA 应用程序。我的 Web 应用程序由一个 Entity、一个 ManagedBean 和一些 JSF 页面组成。它的目的是在 MySQL 数据库中创建并存储一个对象。每次我想将实体持久保存到 PersistenceContxt 中时,都会收到 javax.persistence.TransactionRequiredException 。但是,当将 UserTransaction 注入(inject) Controller 类时,它可以正常工作,但我不明白为什么?因为它应该不需要添加 UserTransaction 因为它是容器管理的。是我错了还是什么?或者我的代码中还有其他问题?

这是我的 ManagedBean 代码:

@ManagedBean
@SessionScoped
public class Controller {
    @PersistenceContext
    private EntityManager em;
    private Book book;
    public Controller() {}

    public Book getBook() {
        return book;
    } 

    public void setBook(Book book) {
        this.book = book;
    }

    public String createBook() {
        book = new Book();
        return "create";
    }

    public String showResponse() {
        em.persist(book);
        return "response";
    }
}

这是create.xhtml Facelet:

...
<h:form>
    <h:panelGrid columns="2">
        <h:outputText>Title</h:outputText>
        <h:inputText value="#{controller.book.title}" />
    </h:panelGrid>
</h:commandButton action="#{controller.showResponse()}" value="Response" />
...

这是Persistence.xml内容:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="JPATestPU" transaction-type="JTA">
    <jta-data-source>jdbc/mysql</jta-data-source>
    <properties>
      <property name="javax.persistence.schema-generation.database.action" value="create"/>
    </properties>
  </persistence-unit>
</persistence>

最佳答案

仅为 EJB 中的方法自动创建事务,而不为托管 bean 自动创建事务。 如果您在 JEE7 容器中,您可以尝试将 @Transactional 添加到您的 Controller 托管 bean 中,否则您需要使用 UserTransation 来管理事务。

这是我使用过的一段代码:

@Transactional
public class PersonService {
    @PersistenceContext 
    private EntityManager em;

    public void savePerson(Person person) {
    em.persist(person);
}

我从 servlet 调用它:

 @WebServlet("/MyServlet")
 public class MyServlet extends HttpServlet {
    @Inject
    PersonService service;
  ....
  service.savePerson(p);
  System.out.println("Person saved");

我可以在数据库中看到它已保存,并且在日志中我看到以下消息:

INFO: Managed bean with Transactional annotation and TxType of REQUIRED called outside a transaction context.  Beginning a transaction...
INFO: Person saved

正如您所看到的,新交易已创建并且对象已保存

关于java - 在容器管理的实体管理器中获取 javax.persistence.TransactionRequiredException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24001269/

相关文章:

java - 使用生成的 Id 安全地持久保存新 JPA 实体的最佳实践

java - 当 child 被 orphanRemoval 删除时,EntityListener 不起作用

java - Play JPA - 错误 : Removing a detached instance

java - 如何在java8中使用对象内的List属性进行groupingBy的groupingBy

java - Java 中的文件加密/解密

java - JSF selectonemenu 无法实例化类

java - 尝试使用 DOM 解析 XML 文件时出现 NullPointerException

java - 富人意见箱

java - 使用 selectonemenu 创建 JSF 数据表并从数据库中填充其数据

java - 实体管理器正在重新创建表