我目前正在创建一个EJB3数据访问类来处理Java EE 6应用程序中的所有数据库操作。现在,由于Java EE 6提供了新的ApplicationScoped
注释,我想知道我的EJB应该具有什么状态,或者它应该是无状态的。
让DAO成为@Stateless
会话Bean或@ApplicationScoped
Bean会更好吗?那么@Singleton
呢?这些与DAO相关的选项有何不同?
修改 我正在使用Glassfish 3.0.1和完整的Java EE 6平台
答案 0 :(得分:14)
让DAO成为@Stateless会话Bean或@ApplicationScoped Bean会更好吗? @Singleton怎么样?这些与DAO相关的选项有何不同?
我不会将无状态会话Bean用于DAO:
EJB由容器池化,因此如果每个池有N个实例和数千个表,那么您只会浪费资源(甚至不会提及部署时的成本)。
实现DAO作为SLSB会鼓励EJB链接,从可扩展性的角度来看这不是一个好的做法。
我不会将DAO层绑定到EJB API。
EJB 3.1中引入的@Singleton
可以使事情变得更好但我仍然不会将DAO实现为EJB。我宁愿使用CDI(也许是自定义构造型,例如参见this article)。
或者我根本不会使用DAO。 JPA的实体管理器是Domain Store模式的实现,并且在DAO中对域存储的包装访问不会增加太多价值。
答案 1 :(得分:1)
经过一番反思,似乎DAO实际上并不是我想做的正确名称。帕斯卡尔说,也许它真的是一个门面。 我刚刚找到了Netbeans Petstore示例 - 一个JavaEE6示例应用程序,请参阅here - 其中有一个 ItemFacade ,它负责从数据库中查找/创建/删除实体。这是一个无状态会话Bean。看起来像这样:
@Stateless
public class ItemFacade implements Serializable {
@PersistenceContext(unitName = "catalogPU")
private EntityManager em;
public void create(Item item) { ... }
public void edit(Item item) { ... }
public void remove(Item item) { ... }
public Item find(Object id) { ... }
public List<Item> findAll() { ... }
public List<Item> findRange(int maxResults, int firstResult) { ... }
public int getItemCount() { ... }
}
所以作为一个结论我不再称呼我的DAO DAO,而只是例如PersonEJB(我认为“PersonFacade”可能会被误解)并使其成为@Stateless,因为我认为Netbeans的例子也可以被认为是 - 设计。
答案 2 :(得分:0)
@Pascal: 在我看来,由于容器管理这些服务,我的DAO不对交易或安全性“负责”。我只是在我的DAO中注释方法(仅用于安全性,因为事务是自动处理的)。注释是否已经“责任”?
好的,所以你让我重新考虑一下我的设计。希望它没关系,也不是太偏离主题,但也许有帮助 - 这就是我今天使用JEE6的方式:
这种方法有问题吗?