2010-04-22 102 views
2

我使用的是JEE6堆栈包括JPA 2.0,JSF 2.0,EJB 3.1等我正确使用EJB吗?

的方式我的架构设置如下:

我有JPA使用Hibernate作为我JPA提供商注释的DAO。 我有与我的facelet/xhtml页面相对应的JSF托管bean。 我有处理所有数据库请求的EJB。

我的XHTML页面有调用我的托管bean的JSF EL。我的托管bean包含对由EJB管理的DAO实体的引用。例如,我有一个映射到数据库表的用户实体。我有一个用户EJB来处理所有返回用户的CRUD操作。我有一个编辑用户的页面。高级工作流程将是:导航到用户编辑页面 - > EL调用位于加载用户的托管bean中的方法。该方法从EJB调用userEJB.loadUser(user)以从数据库获取用户。用户被编辑并提交 - >一个函数在托管bean中调用,它调用EJB中的一个函数来保存用户。等等

我遇到了使用EJB访问我的JSF页面中的数据的问题。 我有很多懒惰初始化错误的问题,我相信这是由于我已经设置好了。

例如,我有一个客户端实体,它具有一个延迟加载的用户列表。为了得到 一个客户端,我在我的EJB中调用一个到数据库的方法,找到一个客户端并返回它。后来在 我希望访问这个客户的用户列表,为了做到这一点,我必须通过调用某种方法来加载这些用户(因为他们被懒惰地加载)回到EJB。这意味着,我要创建一个方法,如

public List<User> getUserListByClient(Client c) 
{ 
    c = em.merge(c); return c.getUserList(); 
} 

这种方法的唯一目的是加载用户(我不连阳这种做法是好还是作品)。 如果我自己在做会话管理,我想让整个请求的会话都打开并直接访问该属性,这将会很好,因为会话将会打开,似乎有一个额外的间接层EJB让我感到困难。

我喜欢EJB,因为我喜欢它们受容器控制,共享,提供免费事务管理等事实。但是,我感觉我错误地使用它们,或者我已经设置了我的JSF应用程序不正确。

任何反馈将不胜感激。

感谢,

回答

1

您的使用似乎好。请记住,em.merge(c)可能会将对Client c所做的更改保存到数据库中。如果你只是想获得客户端C的UserList的不保存到客户端C所做的更改,那么你可以这样做:

public List<User> getUserListByClient(Client c) 
{ 

    Client client = em.find(Client.class, c.clientId); 
    return client.getUserList(); 

} 

或者更好的,只是给委托人身份证到getUserListByClient强似全客户端对象,只是为了节省一个tinsy winsy位的内存:)

2

如果我在做会话管理 我自己,我想刚离开 会话打开整个请求 和直接访问属性,这 将罚款作为会议将是 开放反正

事实上,这就是open session in view模式(也称为开放的EntityManager在视图)。它也可以与EJB一起使用。理想情况下,事务应该在业务层/ EJB中进行管理,因此可以看到这与纯层架构略有偏差。但它解决了视图中延迟加载的问题,并且很容易。

否则,您必须确保急切地加载交易结束后将使用的信息。或者你可以依靠DTO,但是它开始很麻烦。

这里有两个覆盖的话题和讨论利弊/利弊和替代链接: