需要设计结构的帮助,并在helper的帮助器中查找EntityManager和UserTransaction

时间:2009-04-28 17:30:46

标签: hibernate jpa java-ee persistence jndi

我基本上是一个新手,他开始使用新的webapp。 webapp主要是您的基本CRUD操作。为此,我决定将JPA与Hibernate一起用作持久性提供程序,并将在Apache Derby上进行开发以进行开发和测试。我使用GlassFish v2作为App Server来部署我的EJB3 bean。对于前端我使用的是JSF(带有woodstock主题的Visual JSF,与NeatBeans v6.5捆绑在一起)

所以这就是我到目前为止的进展方式。我一直在使用NetBeans 6.5向导来生成我的实体类和ejb会话bean。我所做的是,我在Apache Derby中创建了一个新表,比如XXX。然后我使用“来自数据库的实体类”来生成XXX实体类,其中包含所有必要的注释以及getter和setter方法。

接下来,我运行“来自实体类的JPA控制器类”向导来生成控制器类代码,XXXJpaController基本上包含以下内容:

@Resource private UserTransaction utx = null;
@PersistenceUnit(unitName = "TestEnterpriseApplication-ejbPU") private EntityManagerFactory emf = null;
1. EntityManager getEntityManager() { return emf.createEntityManager() }
2. void create(XXX xxx) throws PreexistingEntityException, RollbackFailureException, Exception{}
3. void edit(XXX xxx) throws NonexistentEntityException, RollbackFailureException, Exception{}
4. void destroy(Long id) throws NonexistentEntityException, RollbackFailureException, Exception {}
5. List<XXX> findXXXEntities(){}
6. List<XXX> findXXXEntities(int maxResults, int firstResult)  {}
7. List<XXX> findXXXEntities(boolean all, int maxResults, int firstResult){}
8. XXX findXXX(Long id){}
9. int getXXXCount(){}

然后,我运行“实体类的会话Bean”向导来生成EntityFacade本地/远程会话bean,可以在需要时由前端调用,如下所示:

@PersistenceContext private EntityManager em;
1. void create(XXX xxx) { em.persist(xxx); }
2. void edit(XXX xxx) { em.merge(xxx); }
3. void remove(XXX xxx) { em.remove(em.merge(xxx)); }
4. List<XXX> findAll() { return em.createQuery("select object(o) from XXX as o").getResultList();  }

由于我已经拥有了生成这些方法的generatd Controller类,并且更好地支持try和catch以及事务,我决定在XXXFacade.java中调用它,如下所示:

XXXJpaController XXXController = new XXXJpaController();
1. public void create(XXX xxx) throws PreexistingEntityException, RollbackFailureException, Exception {
        XXXController.create(xxx); }
2. public void edit(XXX xxx) throws NonexistentEntityException, RollbackFailureException, Exception{
        XXXController.edit(xxx); }
3. public void remove(XXX xxx) throws NonexistentEntityException, RollbackFailureException, Exception{
        XXXController.destroy(xxx.getId()); }
4. public XXX find(Object id) {
        return XXXController.findXXX((Long)id); }
5. public List<XXX> findAll() {
        return XXXController.findXXXEntities(); }

所以这是我的第一个问题。这是在JEE世界中做事的正确方法还是有更好的方法呢?我在这里介绍一些冗余吗?这是我一直关注所有实体类的模式:创建实体类 - &gt;创建控制器类 - &gt;创建entityfacade类 - &gt;更改entityfacade类以调用控制器类方法

ps:我正在使用JTA

这反过来又引发了另一个问题。所有生成的控制器类都有自己的getEntityManager()方法。因此,为了摆脱这种冗余,我决定使用HibernateUtil.java中的一个辅助类,这在Hibernate教程中很常见(它充当sessionfactory的单例)。所以我创建了一个PersistenceUtil.java,它有getEntityManager()和getUserTransaction()方法,它们应该返回Controller类使用的EntityManager和UserTransaction实例。

这就是问题所在。我在XXXFacade类上使用@PersistenceContext((name =“jpa / EntityManager”)和@Resource(name =“jta / UserTransaction”)。所以我可以从XXXFacade类访问em和utx的JNDI条目(如果我必须,但在我的情况下,我不在)和XXXJpaController助手类(通过jndi查找)。在线阅读后,这就是我发现的。帮助程序类需要在bean的组件环境中使用JNDI查找( java:comp / env)因为注入仅针对容器管理bean而不针对非托管辅助类进行。这适用于在XXXFacade类中实例化的Controller类,如上面的代码所示。但是,我无法使用PersistenceUtil类用于查找EntityManager或UserTransaction,因为我猜它是一个帮助器的助手类。我可以做些什么来解决这个问题并在PersistenceUtil帮助器类中访问容器管理实体管理器和usertransaction?我想到的一个选项是在每个XXXFacade类中实例化Persistence类(我不喜欢它的声音)。

我能想到的其他选项是摆脱Controller类并将所有代码移到XXXFacade类中。这样我就不再需要PersistenceUtil辅助类,因为我可以直接将它注入会话bean,对吗?

就像我刚开始提到的那样,我是一个新手。我希望听取所有经验丰富,经验丰富的java / jee老手的意见,以获得有关此问题的指导。我可以在这里使用任何特定的模式吗?

如果对您没有任何意义,我很抱歉。请随时向我询问任何澄清,我将非常乐意这样做。

2 个答案:

答案 0 :(得分:1)

您可能想要研究的一件事是Spring用于管理您的交易,而不是使用工厂方法。

你在这里有很多,就像一条建议,我发现更容易消化的问题是你得到的更好的答案,不仅仅是在Stack Overflow上,而是在互联网上。我理解,面对很多新技术来形成明确的问题可能很困难,我自己的问题历史有一些巨大的问题,但重要的是在要求别人帮助你之前澄清你的想法和问题。您可能希望将其分解为几个问题,重点是明确提出一个问题。一般来说,如果你事先花时间提出一个明确的问题,那么人们会更容易帮助你。

答案 1 :(得分:0)

是的..你是对的。我为问题格式道歉。这实际上是我在stackoverflow上的第一篇帖子,因此问题的丑陋。无论如何,感谢您的反馈,我试图发布更好的问题。

无论如何,我找到了问题的答案。我决定不使用控制器类,只使用实体的会话外观bean。我使用容器管理持久性。因此不再需要getEntityManager()方法或辅助类。而是使用“@PersistenceContext”形式的DI。此外,由于我使用容器管理持久性,我不再需要UserTransactions。