我的实体不会持久显示javax.persistence.TransactionRequiredException

时间:2015-07-24 12:12:24

标签: jpa transactions eclipselink

我最近在Eclipse IDE中的TomEE 1.7中迁移到JPA 2.0(EclipseLink 2.4.2 Juno),因为我正在存储它们存储和检索的值,但是在使用时它们不会持久存储到数据库中{ {1}}显示entitymanager.flush()这是我的代码

Create.java(注册方法)

javax.persistence.TransactionRequiredException

的persistence.xml

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;

    }

我无法弄清楚问题数据是否已被检索并存储,但它没有更新,也没有在数据库中持久化

2 个答案:

答案 0 :(得分:1)

commit()方法立即提交您的交易。因此,这些变化正在写入数据库&您之前打开的交易也会在此时结束。当您之后致电flush()时,没有公开的交易,因此flush()操作会在您遇到此问题时抱怨javax.persistence.TransactionRequiredException。另请参阅javax.persistence Interface EntityManager#flush()

  

void flush()

     

将持久性上下文与基础数据库同步。

     

抛出:   TransactionRequiredException - 如果没有事务

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

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 ...)与后端代码混合使用。这通常被认为是“意大利面条”的反模式。

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

答案 1 :(得分:0)

错误表示您无法在事务外调用flush。您的代码清楚地显示您在调用manager.getTransaction()。commit()后正在调用flush。提交后不需要调用flush,因为entityManager在提交或刷新时同步到数据库。如果您有一个长时间运行的事务并且想要在特定阶段进行同步,则只使用flush。

对于其余部分,打开EclipseLink日志记录https://wiki.eclipse.org/EclipseLink/Examples/JPA/Logging,它将显示您希望它正在提交/刷新调用。