Search code examples
jpatransactionseclipselink

My entities are not persisting showing javax.persistence.TransactionRequiredException


I have recently migrated to JPA 2.0 (EclipseLink 2.4.2 Juno) in TomEE 1.7 in Eclipse IDE, As i am storing the values they are getting stored and retrieved fine, but they are not persisting into the database when is use entitymanager.flush()it is showing javax.persistence.TransactionRequiredException Here is my code

Create.java (register method)

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>

I cant figure out the problem data is getting retreived and stored but it is not updating and not getting persisted in database


Solution

  • The commit()method is committing your transaction immediately. Therefore, the changes are writting into the database & your previously open transaction also ends in this moment. When you call flush() afterwards, there is no open transaction so the flush() operation - complains as you experience it - with a javax.persistence.TransactionRequiredException. See also javax.persistence Interface EntityManager#flush()

    void flush()

    Synchronize the persistence context to the underlying database.

    Throws: TransactionRequiredException - if there is no transaction

    You should call the commit() method after you synced the state of your EntityManager, like so

    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();
    

    Another hint:

    You should avoid to mix your UI-side code (JSF...) with Backend code. This is generally considered 'spaghetti' anti-pattern here.

    Moreover, do not open and close EntityManagerFactory every time (!) you call this UI-bound method (register(...)), as this is a performance killer - at least it produces unnecessary processing every time somebody tries to register here. At least, you should create an instance of EntityManagerFactory (or: EntityManager) as a field (via a DBService class) and reuse this to communicate with the application backend.