0
votes

I'm maintaining some old code, that some not-so-clever developer once wrote (Me.), and when I tried to push a new update, suddenly it stopped working.

Basically I have a BUNCH of DAO's which is used in a lot of different threads. All DAO's extend the class:

public class DAO {

    /**
     * The entitymanager.
     */
    private EntityManager entitymanager;


    /**
     * Gets the entitymanager
     *
     * @return the manager
     */
    public EntityManager getManager() {
        entitymanager = FactoryMaker.getFactory().createEntityManager();
        entitymanager.getTransaction().begin();
        entitymanager.flush();
        entitymanager.clear();
        return entitymanager;

    }

    /**
     * Commit and clear the manager.
     */
    public void Close() {
        if (entitymanager.isOpen()) {
            if (entitymanager.getTransaction().isActive()) {
                entitymanager.getTransaction().commit();
                entitymanager.clear();
            }

            entitymanager.close();
        }
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
    }

}

So when a DAO is used, the following code is executed (e.g.)

    /**
 * Gets a profiletype based on the specified name.
 *
 * @param name the name
 * @return the by name
 */
public Profiletype getByName(String name) {

    EntityManager manager = getManager();
    TypedQuery<Profiletype> query = manager.createQuery("SELECT w FROM Profiletype w WHERE w.name='" + name + "'", Profiletype.class);

    Profiletype result = query.getSingleResult();
    Close();
    return result;
}

And this actually did the job. Well it's not pretty, but it worked. I'm using glassfish to manage the connections, so my persistence.xml looks like:

<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1"
             xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="dtv4" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/__default</jta-data-source>

        <class>...</class>
        <class>...</class>


        <properties>
            <property name="eclipselink.logging.level" value="INFO"/>
            <property name="eclipselink.ddl-generation" value="none"/>
            <property name="eclipselink.query-results-cache" value="false"/>
            <property name="eclipselink.refresh" value="true"/>

        </properties>
    </persistence-unit>
</persistence>

And I've actually just looked inside the running WAR, and It's the same persistence.xml and DAO class. But a quick google search shows that it's illegal (not possible!) to call entitymanager.getTransaction().begin(); when using JTA.

And of course, now I'm getting the error

java.lang.IllegalStateException: 
Exception Description: Cannot use an EntityTransaction while using JTA.

Now my question is: How can I fix this, without rewriting everything? It's on my list, but right now I just want to push the update. I've read that you can use @PersistenceContext and such, but it doesn't seem to work, when my DAO is just a normal Java class.

I hope some bright mind can help me.

Best regards.

1
So you must use JTA? Is it a requirement?pirho
glasfish is stronger to JTA (I'm not specjalist ok or not), the same application (JPA:eclipselink) execute transactions slight differer in TomEE Plume (one step more liberal)Jacek Cz
@pirho Yes. It is.Benjamin Larsen
Have you already studied the alternative to make DAO -for example- @LocalBean what options there are with that and what these options involve?pirho

1 Answers

0
votes

EclipseLink documentation refers that it could be configured the TargetServer that will be used to enable integration with a host container https://www.eclipse.org/eclipselink/api/2.6/org/eclipse/persistence/config/TargetServer.html. Try put in the persistence.xml the property

<property name="eclipselink.target-server" value="Glassfish"/>

Using this property make sure that the dynamically created EntityManager will use transaction type JTA. Hope this help.