繁体   English   中英

如何在Java EE中保留Entity?

[英]How to persist Entity in java EE?

我试图通过Java EE中的WebSocket调用将条目添加到数据库中,但仍在学习(我肯定还不了解所有概念)。 根据我如何调整代码,我收到以下两个错误:

错误1:java.lang.IllegalStateException:异常描述:使用JTA时不能使用EntityTransaction。

错误2:javax.persistence.TransactionRequiredException

不用说,我什么也没进入数据库。 我的代码和一般设计中可能有一堆东西不是最佳的,欢迎任何建议或指针,但是问题是我应该从哪里去使用户进入数据库?

我正在使用以下简单设置,以便在解决整个问题之前能够正常工作。

我的实体:

@Entity
@Table(name = "USER_TABLE")
public class User implements Serializable {

    @Id
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

我的数据访问对象,最后这应该是User的神奇数据库工作发生的地方:

public class UserDAO {

    private EntityManager mEM;

    public void save(User user) {
        //mEM.getTransaction().begin(); // with comment = error no 2 | no comment = no 1
        mEM.persist(user); // I was thinking that this was the magic I needed.
        //mEM.getTransaction().commit(); // with comment = error no 2 | no comment = no 1
    }

    public void setEM(EntityManager em) {
        mEM = em;
    }
}

我也有一个DatabaseIO,我的想法是,如果我不仅拥有User实体,我想将所有数据库IO的信息收集到一个类中:

public class DatabaseIO {

    private EntityManager mEM;

    public DatabaseIO(EntityManager em) {
        System.out.println("DatabaseIO(" + em + ")");
        mEM = em;
    }

    public void createUser(String name) {
        System.out.println("createUser(" + name + ")");
        User user = new User();
        user.setName(name);

        UserDAO userDAO = new UserDAO();
        userDAO.setEM(mEM);
        userDAO.save(user);
    }
}

然后,我有一些类将使用数据库IO并处理进入应用程序的请求。 基本上是业务逻辑。 我没有将其标记为bean,因为这些是在每个用户连接到应用程序时创建的。 并且一旦它们连接在一起,user1可能需要访问user2的SomeClass对象,不确定如何在不自己创建对象而不是容器的情况下完成此操作。

public class SomeClass {

    private DatabaseIO mDbIO;

    public SomeClass(EntityManager em) {
        mDbIO = new DatabaseIO(em);
    }

    public void newUser(String name) {
        mDbIO.createUser(name);
    }
}

我有一个从应用程序开始并拥有所有应用程序状态的EJB,但不确定这是最好的(很可能有更好的方法,我的目标是不要将我经常需要的东西放到数据库中,直到完成),但到目前为止,这是我想出的:

@Startup
@Singleton
@Named("some_manager")
public class SomeApplicationManager {

    @PersistenceContext(unitName="AddUsersPU")
    private EntityManager mEM;

    public EntityManager getEM() {
        return mEM;
    }
}

最后是我的WebSocket端点:

@ServerEndpoint("/WebSocket")
public class WebEndpoint {

    @Inject
    SomeApplicationManager mAppManager;

    @OnOpen
    public void onOpen(Session aSession, EndpointConfig aConfig) {
        aSession.addMessageHandler(new MessageHandler.Whole<String>() {
            @Override
            public void onMessage(String aUserName) {
                System.out.println("new user: " + aUserName);
                SomeClass aClassObj = new SomeClass(mAppManager.getEM());
                aClassObj.newUser(aUserName);
            }
        });
    }

}

我已经用一个简单的JavaScript进行了测试,得到了我期望的输入,直到UserDAO中的行(我已经注释了)都出现了错误。

编辑:据我了解,从下面的答案以及更多的谷歌搜索中,mEM.persist(user)不起作用的原因是因为它不受容器管理。 我试图通过将UserDAO注释为@Stateless并将其通过@EJB注入到DatabaseIO中来进行补救,如建议的那样。 但是,这给了我一个NullPointerException。 然后,我还将DatabaseIO和SomeClass标记为@Stateless,而不是在WebEndpoint中显式创建SomeClass(以及SomeClass中的DatabaseIO),而是将其注入@EJB。 在这一点上,我实际上已经将一个实体放入数据库中,但是我不确定我是否理解全部。

使您的UserDAO成为会话Bean,并使用@PersistenceContext批注在其中注入持久性上下文。 错误1的原因是您正在使用JTA,因此不允许您管理事务,并且在输入EJB方法时将获得一个事务(除非您未明确指定事务)。 而且您不需要任何单例来提供持久性上下文,容器将对其进行处理。

@Stateless
public class UserDAO {

    @PersistenceContext(unitName="AddUsersPU")
    private EntityManager mEM;

并使用@EJB注释注入EJB

@EJB
private UserDAO userDao;

这就是您所需要的,不要在其中设置EM,即,删除

public void setEM(EntityManager em)`

方法

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM