前回、JBoss 7.1 (Java EE6 標準) を使用してアプリを開発したとき、DAO を使用して永続化レイヤーを作成しました。
まず第一に、すべての具体的な daos の父である「抽象的な」DAO がありました。
public abstract class AbstractDao<T> {
private Class<T> entityClass;
private String defaultSortColumn;
public AbstractDao(Class<T> entityClass) {
this.entityClass = entityClass;
this.defaultSortColumn = "";
}
protected abstract EntityManager getEntityManager();
public void create(T entity) {
getEntityManager().persist(entity);
}
public void edit(T entity) {
getEntityManager().merge(entity);
}
public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
@SuppressWarnings("rawtypes")
public List<T> find() {
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery();
Root from = cq.from(entityClass);
cq.select(from);
return getEntityManager().createQuery(cq).getResultList();
}
@SuppressWarnings("rawtypes")
public int count() {
//...
}
}
次に、ドメイン内のDB エンティティごとに 1 つの dao 実装があります。
それらはすべて互いに非常に似ており、通常の「crud」操作よりも複雑なクエリのメソッドを追加するだけです。
一例を次に示します。
@Stateless
public class ShopDao extends AbstractDao<Shop> {
@Inject
private EntityManager em;
@Override
protected EntityManager getEntityManager() {
return em;
}
public ShopDao() {
super(Shop.class);
}
}
ご覧のとおり、私の DAO はステートレス EJB です。
この方法でアプリは機能しますが...新しいエンティティを作成する必要がある場合、エンティティ自体とDAOの両方を作成する必要があります。ちょっと冗長ですよね?ただし、特定のエンティティに対して複雑なクエリを実行する必要があることがよくあるため、これ以上の方法は考えられません。
質問は次のとおりです。
これはベストプラクティスですか?永続化レイヤーを他にどのように設計できますか?
DAO が EJB であることは良いことですか?
クライアント側(JSFコントローラー)で検証があります。永続層にある必要がありますか?どのように?
DAO を避けて、生の EntityManager をサービス層クラスに持つ方がよいでしょうか?
編集
各テーブルに 1 つの dao を持たないようにする方法はありますか?