Java EE中EJB注入通用CRUD DAO后无法访问方法的问题咨询
解决泛型CRUD抽象类注入后无法访问通用方法的问题
看起来你遇到的核心问题是接口继承关系没理顺——你的ICategoryDaoRemote没有继承通用的IGenericDaoRemote<Category>,导致注入后没法调用通用CRUD方法。咱们一步步来修复:
1. 让实体DAO接口继承通用远程/本地接口
首先修改你的ICategoryDaoRemote,让它继承IGenericDaoRemote<Category>,这样它会自动继承所有通用CRUD方法:
public interface ICategoryDaoRemote extends IGenericDaoRemote<Category> { // 这里可以添加Category专属的DAO方法(如果需要的话) }
同样,本地接口也要对应继承:
public interface ICategoryDaoLocal extends IGenericDaoLocal<Category> { // 专属方法写在这里 }
2. 确认DAO实现类的结构(无需修改)
你的CategoryDao已经正确继承了GenericDao<Category>并实现了上述两个接口,这部分是没问题的:
@Stateless @Remote(ICategoryDaoRemote.class) @Local(ICategoryDaoLocal.class) public class CategoryDao extends GenericDao<Category> implements ICategoryDaoRemote, ICategoryDaoLocal { // 不需要重复实现通用方法,抽象类GenericDao已经帮你搞定了 }
3. Service层现在可以正常调用通用方法了
现在你在CategoryService里注入ICategoryDaoRemote后,就能直接调用add/remove/update/getAll这些通用方法,同时也能调用Category专属的DAO方法(如果定义了的话):
@Stateless @Local(ICategoryServiceLocal.class) @Remote(ICategoryServiceRemote.class) public class CategoryService implements ICategoryServiceRemote, ICategoryServiceLocal { @EJB private ICategoryDaoRemote categoryDao; public void addCategory(Category category) { categoryDao.add(category); // 现在可以正常调用了! } public List<Category> getAllCategories() { return categoryDao.getAll(Category.class); } }
额外优化:简化getAll方法的调用
你可能注意到getAll方法需要传入Class<T>参数,这是因为Java泛型的类型擦除机制。可以通过在抽象类里传入实体类型来简化:
修改GenericDao,添加构造函数接收实体类型:
public abstract class GenericDao<T> implements IGenericDaoLocal<T>, IGenericDaoRemote<T> { @PersistenceContext(name = "postgresPersistant") private EntityManager entityManager; private final Class<T> entityClass; // 子类必须调用该构造函数传入实体类 protected GenericDao(Class<T> entityClass) { this.entityClass = entityClass; } @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); } // 优化后的getAll,无需传参 @Override public List<T> getAll() { Session session = entityManager.unwrap(Session.class); Criteria criteria = session.createCriteria(entityClass).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); return criteria.list(); } }
然后修改CategoryDao的构造函数:
public class CategoryDao extends GenericDao<Category> implements ICategoryDaoRemote, ICategoryDaoLocal { public CategoryDao() { super(Category.class); } }
对应的通用接口也要更新getAll方法的签名:
public interface IGenericDaoRemote<T> { void add(T t); void remove(T t); void update(T t); List<T> getAll(); // 去掉Class<T>参数 }
这样Service层调用就更简洁了:
public List<Category> getAllCategories() { return categoryDao.getAll(); }
内容的提问来源于stack exchange,提问作者Suule
相关产品推荐
相关产品推荐

