JPA - 在持久化实体时获取“需要交易”的例外

时间:2015-11-12 05:05:32

标签: java hibernate maven jpa wildfly

我已经设置了maven应用程序并运行了wildfly服务器。我有一个mySql数据源,我可以使用我的EntityManager读取,但在每次尝试持久化我的实体时,我得到错误说“javax.persistence.TransactionRequiredException:没有事务正在进行中”

Bellow是我的BaseDao课程

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class BaseDao {

    private static final String PERSISTENCE_UNIT_NAME = "MySqlDS";
    private EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

    public EntityManager getEntityManager() {
        return factory.createEntityManager();
    }

}

我的persistemce.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="MySqlDS" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:/MySqlDS</jta-data-source>
        <class>main.java.yas.entity.User</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
            <property name="hibernate.connection.charSet" value="UTF-8"/>
            <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />
        </properties>
    </persistence-unit>
</persistence>

我调用管理器的服务类如下:

public class UserService {

    @EJB
    private UserManager manager;

    public String createNewUser_test(String name) {
        return manager.createNewUser_test(name);
    }
}

我的经理班是这样的:

import javax.ejb.*;
import javax.persistence.EntityManager;

@Stateless
public class UserManager {

    public String createNewUser_test(String name) {

        BaseDao dao = new BaseDao();
        EntityManager em = dao.getEntityManager();
        try {
            User user = new User();
            user.setFirstName(name);
            user.setLastName(name);
            user.setRole(UserRole.RegistredUser);
            user.setEmail("email@email.com");

            em.persist(user);

        }
        finally {
            em.flush();
            em.close();
        }

    }
}

我已经检查过,我在wildfly standalone.xml文件中声明了“jta = true”。

你可以告诉我我的申请有什么问题吗?

更新:  我应用了一些评论者建议的一些变化。现在我在服务类中获取NPE,我正在调用管理器来创建新用户。

2 个答案:

答案 0 :(得分:0)

删除@TransactionAttribute属性,默认设置为REQUIRED,这对您来说已经足够了。

如何获取UserManager对象?

如果您希望容器使用该方法自动启动事务,则必须进行容器管理,这意味着您的bean必须注入:

@EJB
UserManager userManager;

答案 1 :(得分:0)

您手动实例化DAO,并手动构建持久性单元。执行此操作时,即使您已在persistence.xml中配置了JTA,也不会启用JTA。在这种情况下你有没有理由不能使用注射剂?

如果您想切换到注射,基于您现在正在做的事情的一个非常简单的方法将是这样的。

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class BaseDao {
    @PersistenceContext(unitName="MySqlDS")
    private EntityManager entityManager;

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

import javax.ejb.EJB;
import javax.ejb.Stateless;

@Stateless
public class UserManager {
    @EJB
    private BaseDao baseDao;
    public String createNewUser_test(String name) {
        User user = new User();
        user.setFirstName(name);
        user.setLastName(name);
        user.setRole(UserRole.RegistredUser);
        user.setEmail("email@email.com");

        baseDao.save(user);
        return "";
    }
}

在此示例中,容器会为您实例化您的类,并可根据需要提供资源,例如此处提供的EntityManager