如何为简单的CRUD操作(JavaEE、EJB注入)实现通用dao

如何为简单的CRUD操作(JavaEE、EJB注入)实现通用dao,java,jakarta-ee,ejb,dao,Java,Jakarta Ee,Ejb,Dao,我目前正在重构我的代码,我注意到我可以使用泛型抽象类进行CRUD操作。 但不幸的是,我被困在正确的位置。 问题是,当我将DAO类注入服务类时,我需要使用实体的远程接口(在我的案例类别中),请参见下面的代码 通用dao的远程接口 public interface IGenericDaoRemote<T> { void add(T t); void remove(T t); void update(T t); List<T> getAll(Class<T> typ

我目前正在重构我的代码,我注意到我可以使用泛型抽象类进行CRUD操作。 但不幸的是,我被困在正确的位置。 问题是,当我将DAO类注入服务类时,我需要使用实体的远程接口(在我的案例类别中),请参见下面的代码

通用dao的远程接口

public interface IGenericDaoRemote<T> {
void add(T t);
void remove(T t);
void update(T t);
List<T> getAll(Class<T> type);
}
@Stateless
@Remote(IGenericDaoRemote.class)
@Local(IGenericDaoLocal.class)
public abstract class GenericDao<T> implements IGenericDaoLocal<T>, IGenericDaoRemote<T> {
    @PersistenceContext(name = "postgresPersistant")
    private EntityManager entityManager;

    @Override
    public void add(T t) {
        Session session = entityManager.unwrap(Session.class);
        session.save(t);
    }

    @Override
    public void remove(T t) {
        Session session = entityManager.unwrap(Session.class);
        session.delete(t);
    }

    @Override
    public void update(T t) {
        Session session = entityManager.unwrap(Session.class);
        session.update(t);
    }

    @Override
    public List<T> getAll(Class<T> type) {
        Session session = entityManager.unwrap(Session.class);
        Criteria criteria = session.createCriteria(type).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        return criteria.list();
    }
}
公共接口IGenericDaoRemote{ 无效添加(T); 脱空(T); 无效更新(T); 列表getAll(类类型); } 抽象类泛型dao

public interface IGenericDaoRemote<T> {
void add(T t);
void remove(T t);
void update(T t);
List<T> getAll(Class<T> type);
}
@Stateless
@Remote(IGenericDaoRemote.class)
@Local(IGenericDaoLocal.class)
public abstract class GenericDao<T> implements IGenericDaoLocal<T>, IGenericDaoRemote<T> {
    @PersistenceContext(name = "postgresPersistant")
    private EntityManager entityManager;

    @Override
    public void add(T t) {
        Session session = entityManager.unwrap(Session.class);
        session.save(t);
    }

    @Override
    public void remove(T t) {
        Session session = entityManager.unwrap(Session.class);
        session.delete(t);
    }

    @Override
    public void update(T t) {
        Session session = entityManager.unwrap(Session.class);
        session.update(t);
    }

    @Override
    public List<T> getAll(Class<T> type) {
        Session session = entityManager.unwrap(Session.class);
        Criteria criteria = session.createCriteria(type).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        return criteria.list();
    }
}
@无状态
@远程(IGenericDaoRemote.class)
@本地(IGenericDaoLocal.class)
公共抽象类GenericDao实现IGenericDaoLocal、IGenericDaoRemote{
@PersistenceContext(name=“postgresPersistant”)
私人实体管理者实体管理者;
@凌驾
公共无效添加(T){
Session Session=entityManager.unwrap(Session.class);
session.save(t);
}
@凌驾
公共空间移除(T){
Session Session=entityManager.unwrap(Session.class);
删除(t);
}
@凌驾
公共无效更新(T){
Session Session=entityManager.unwrap(Session.class);
更新(t);
}
@凌驾
公共列表getAll(类类型){
Session Session=entityManager.unwrap(Session.class);
Criteria=session.createCriteria(类型).setResultTransformer(Criteria.DISTINCT\u ROOT\u实体);
返回条件。list();
}
}
dao类示例:

@Stateless
@Remote(ICategoryDaoRemote.class)
@Local(ICategoryDaoLocal.class)
public class CategoryDao extends GenericDao<Category> implements ICategoryDaoRemote, ICategoryDaoLocal {
}
@无状态
@远程(ICategoryDaoRemote.class)
@本地(ICategoryDaoLocal.class)
公共类CategoryDao扩展了GenericDao,实现了iCategoryDAO远程、iCategoryDAO本地{
}
服务类别:

@Stateless
@Local(ICategoryServiceLocal.class)
@Remote(ICategoryServiceRemote.class)
public class CategoryService implements ICategoryServiceRemote, ICategoryServiceLocal {

    @EJB
    private ICategoryDaoRemote categoryDao; // <-- here is a problem
.
.
.
}
@无状态
@本地(ICategoryServiceLocal.class)
@远程(ICategoryServiceRemote.class)
公共类CategoryService实现了ICategoryServiceRemote、ICategoryServiceLocal{
@EJB

私有ICategoryDaoRemote categoryDao;//Di您真的需要远程吗?如果您不打算将bean公开给一些单独的应用程序,只需使用本地接口即可

这不是“唯一的区别”。这是一个巨大的区别。 仅当您希望从集群中的另一个节点访问一个节点上的EJB时,或者如果您希望从另一个EAR访问一个EAR中的EJB时,才需要远程

我建议如下:

  • 删除远程接口:接口和引用的定义

  • 在本地接口中定义所需的方法


  • 不幸的是,是的,但即使我可以,结果不是一样的吗?唯一的区别是私有的ICategoryDaoLocal类别Dao中的更改;你是对的,但“差异”指的是当前代码中的差异,即使我可以使用本地接口,也无助于解决我的问题,至少我认为不会。是的,我需要远程,我有多个EJB项目,一个EAR项目正在jBoss app server上工作,并且正在与另一个app server通信,简单的分布式系统如果你真的需要远程接口,可以,然后删除本地接口。你需要本地接口做什么?
    icategorydaomote
    必须扩展
    igenericdaomote