Java EE 6注释继承的神秘面纱

我在几个方案中使用EJB继承,有时在超类中使用注释,就像这个通用的entityDAO:
public class JpaDAO<T>{
    protected Class<T> entityClass;

    @PersistenceContext(unitName="CarrierPortalPU")
    protected EntityManager em;
    protected CriteriaBuilder cb;

    @postconstruct
    private void init() {
        cb = em.getCriteriaBuilder();
    }

    public JpaDAO(Class<T> type) {
        entityClass = type;
    }

    @TransactionAttribute(TransactionAttributeType.required)
    public void create(T entity) {
        em.persist(entity);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public T find(Object id) {
        return em.find(entityClass,id);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public List<T> findAll(){
        CriteriaQuery<T> cq = cb.createquery(entityClass);
        Root<T> entity = cq.from(entityClass);
        cq.select(entity);
        return em.createquery(cq).getResultList();
    }

    @TransactionAttribute(TransactionAttributeType.required)
    public void remove(T entity) {
        em.remove(em.merge(entity));
    }

    @TransactionAttribute(TransactionAttributeType.required)
    public T edit(T entity) {
        return em.merge(entity);
    }

}

使用如下实现的示例子类:

@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class DepartmentDAO extends JpaDAO<Department> {

    public DepartmentDAO() {
        super(Department.class);
    }

    public Department findByName(String name){
        CriteriaQuery<Department> cq = cb.createquery(Department.class);
        Root<Department> department = cq.from(Department.class);
        cq.where(cb.equal(department.get(Department_.name),name));
        cq.select(department);
        try{
            return em.createquery(cq).getSingleResult();
        }catch(Exception e){
            return null;
        }
    }
}

我最近读到java注释不是继承(source).这应该导致我的JpaDAO在访问其实体管理器或其标准对象时抛出空指针异常(因为@PersistanceContext和@postconstruct都将被忽略),但是不是这样.有人可以澄清这个真的有效吗?我非常担心超类中的@TransactionAttributes会发生什么情况,当子类具有NOT_SUPPORTED作为类认值时,可以信任一个required实际使用从子类调用的事务吗?

解决方法

Java注释不被继承,但JavaEE规范更改了规则,以允许这些属性按预期工作.参见常见的注释1.1规范. 2.1节甚至以@TransactionAttribute为例. EJB 3.1第13.3.7.1节还明确说明了@TransactionAttribute的规则:

If the bean class has superclasses,the following additional rules apply.

  • transaction attribute specified on a superclass S applies to the business methods defined by S. If a class-level transaction attribute is not specified on S,it is equivalent to specification of TransactionAttribute(required) on S.
  • A transaction attribute may be specified on a business method M defined by class S to override for method M the transaction attribute value explicitly or implicitly specified on the class S.
  • If a method M of class S overrides a business method defined by a superclass of S,the transaction attribute of M is determined by the above rules as applied to class S.

简而言之,对于大多数JavaEE注释,方法级注释适用于该方法,除非子类覆盖该方法,而类级注解仅适用于该类中定义的所有方法.该规则不适用于“组件定义”类级别注释,例如@Stateless(请参阅EJB 3.1规范第4.9.2.1节)

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...