我的实体没有持续显示 javax.persistence.TransactionRequiredException

My entities are not persisting showing javax.persistence.TransactionRequiredException

我最近在 Eclipse IDE 的 TomEE 1.7 中迁移到了 JPA 2.0 (EclipseLink 2.4.2 Juno),因为我正在存储值,所以它们可以很好地存储和检索,但它们不会持久化到使用时的数据库 entitymanager.flush()它正在显示 javax.persistence.TransactionRequiredException 这是我的代码

Create.java(注册方式)

public static int register(String first, String last, String email,
            String date, String phone, String address, String pin, Login login) {
        try {
            System.out.println("registering persisting the entity");
            EntityManagerFactory emf = Persistence
                    .createEntityManagerFactory("FirstEE");

            EntityManager manager = emf.createEntityManager();

            manager.getTransaction().begin();
            //
            // Query query = manager
            // .createQuery("select l from Truck l");

            Login log = login;

            System.out.println(log.getUsername() + "username"
                    + log.getPassword() + "password");

            User reg = new User();
            reg.setLogin(log);
            reg.setDate(date);
            reg.setEmail(email);
            reg.setFirst(first);
            reg.setLast(last);
            reg.setPhone(phone);
            reg.setAddress(address);
            reg.setPin(pin);

            manager.persist(reg);

            manager.getTransaction().commit();
            manager.flush();
            manager.close();
            emf.close();
            // FacesContext.getCurrentInstance().addMessage("reg:result",
            // new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error Message",
            // "Registered Successfully"));
            FacesContext facesContext = FacesContext.getCurrentInstance();
            FacesMessage facesMessage = new FacesMessage(
                    "Registered Successfully");
            facesContext.addMessage(null, facesMessage);
            System.out.println("after message global");
            return 1;
        } catch (Exception e) {
            System.out.println("hai this is exception caught:" + e);
            System.out.println("hai" + e.getMessage());
            FacesContext.getCurrentInstance().addMessage(
                    "reg:result",
                    new FacesMessage("Something went wrong",
                            "\tSomething went wrong\t"));
            // FacesContext facesContext = FacesContext.getCurrentInstance();
            // FacesMessage facesMessage = new
            // FacesMessage("Something went wrong");
            // facesContext.addMessage(null, facesMessage);

        }
        return 0;

    }

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="FirstEE" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
         <non-jta-data-source>FirstEE</non-jta-data-source>
<!--        <exclude-unlisted-classes>false</exclude-unlisted-classes> -->
        <class>com.jason.Entity.User</class>
        <class>com.jason.ManagedBean.Login</class>

        <properties>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/yash" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="root" />
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="eclipselink.logging.level" value="FINEST" />
            <property name="eclipselink.ddl-generation" value="create-tables" />
        </properties>


    </persistence-unit>
</persistence>

我无法弄清楚问题数据正在检索和存储,但它没有更新,也没有持久保存在数据库中

该错误表明您不能在事务外调用 flush。您的代码清楚地表明您在调用 manager.getTransaction().commit() 之后立即调用 flush。提交后不需要调用刷新,因为 entityManager 在提交或刷新时同步到数据库。只有当您有一个长 运行 事务并且您希望在特定阶段同步时才使用 flush。

对于其余部分,打开 EclipseLink 日志记录 https://wiki.eclipse.org/EclipseLink/Examples/JPA/Logging,它会显示您希望它在 commit/flush 调用中执行。

commit()方法正在立即提交您的事务。因此,更改正在写入数据库,您之前打开的事务也将在此时结束。当您之后调用 flush() 时,没有打开的事务,因此 flush() 操作 - 当您遇到它时会抱怨 - 使用 javax.persistence.TransactionRequiredException。另见 javax.persistence 接口 EntityManager#flush()

void flush()

Synchronize the persistence context to the underlying database.

Throws: TransactionRequiredException - if there is no transaction

您应该在 同步 EntityManager 的状态后调用 commit() 方法 ,就像这样

manager.getTransaction.begin();
// ...
// do something with your entities in between
// ...
manager.persist(reg);
manager.flush(); // in your case: could also be skipped

// finally - if nothing fails - we are safe to commit
manager.getTransaction().commit();

另一个提示:

您应该避免将 UI 端代码 (JSF...) 与后端代码混合。这通常被认为是 'spaghetti' 反模式。

此外,不要每次 (!) 打开和关闭 EntityManagerFactory 你调用这个 UI 绑定方法 (register(...)),因为这是一个性能杀手 - 至少每当有人试图在这里注册时,它都会产生不必要的处理。至少,您应该创建一个 EntityManagerFactory(或:EntityManager)的实例作为字段(通过 DBService class)并重用它来与应用程序后端通信。