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

前端之家收集整理的这篇文章主要介绍了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节)

猜你在找的Java相关文章