Невозможно использовать EntityTransaction при использовании JTA

Я получаю эту ошибку:

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

При попытке использовать JPA и JAVAEE Glassfish.

Мой файл 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="acmeauction">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/MySQLJDBCResource</jta-data-source>
        <class>it.uniroma3.acme.auction.model.User</class>
        <class>it.uniroma3.acme.auction.model.Auction</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/acmeauction"/>
            <property name="javax.persistence.jdbc.user" value="user"/>
            <property name="javax.persistence.jdbc.password" value="password"/>
        </properties>
    </persistence-unit>
</persistence>

То, что я пытаюсь сделать, это сохранить объект (пользователь) таким образом:

@ManagedBean
public class UserRepository implements Serializable{

    @PersistenceUnit
    EntityManagerFactory emf;

    @PersistenceContext
    private EntityManager em; 

    private static UserRepository instance; 

    /**
     * Gives back the singleton UserRepository singleton. 
     */
    public static UserRepository getInstance() {
        if (instance==null) {
            instance = new UserRepository(); 
        }
        return instance; 
    }

    private UserRepository() {
        emf = Persistence.createEntityManagerFactory("acmeauction");
        em = emf.createEntityManager();             
    }

    /** 
     * Save and persist a new User. 
     */
    public void save(User user) {
        em.getTransaction().begin(); 
        em.persist(user);
        em.getTransaction().commit(); 
    }
}

Хотя, если он попытается использовать UserRepository из простого Java-приложения, он будет работать правильно.

Заранее спасибо, АН


person andreaxi    schedule 06.06.2012    source источник


Ответы (2)


Как указано в ошибке, если вы используете JTA для транзакций, вам нужно использовать JTA.

Либо используйте JTA UserTransaction, чтобы начать/зафиксировать транзакцию, либо используйте блок сохраняемости RESOURCE_LOCAL и не-jta DataSource.

См. http://en.wikibooks.org/wiki/Java_Persistence/Transactions.

person James    schedule 06.06.2012
comment
Большое спасибо, это смущает, но я считал, что эта часть кода работает. Спасибо, - person andreaxi; 06.06.2012

Вы не должны использовать em.getTransaction().begin(); или em.getTransaction().commit();, эти инструкции следует использовать с типом транзакции RESOURCE_LOCAL.

В вашем случае транзакция управляется контейнером, при первом использовании EntitiyManager в вашем методе контейнер проверяет, есть ли активная транзакция или нет, если нет активной транзакции, он создает ее, и когда вызов метода заканчивается, транзакция фиксируется контейнером. Итак, в конце ваш метод должен выглядеть так:

public void save(User user) {
    em.persist(user);
}

Контейнер заботится о транзакции, то есть JTA.

person Joe Almore    schedule 12.02.2014