2011-04-04 17 views
10

मैं कुछ स्थितियों में EJB के साथ विरासत का उपयोग कर रहा है, कभी कभी यह सामान्य entityDAO की तरह सुपर क्लास में एनोटेशन के साथ:जावा ईई 6 एनोटेशन विरासत का रहस्य

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; 
     } 
    } 
} 

मैं हाल ही में पढ़ा है कि जावा एनोटेशन नहीं ली गई है (source)। इससे मेरे जेपीडीएओ को अपने इकाई प्रबंधक या इसके मानदंडबिल्डर का उपयोग करते समय एक शून्य सूचक अपवाद फेंकना चाहिए (क्योंकि @PersistanceContext और @PostConstruct दोनों को अनदेखा कर दिया जाएगा), हालांकि यह मामला नहीं है। क्या कोई स्पष्टीकरण दे सकता है कि यह वास्तव में कैसे काम करता है? मैं सुपरक्लास में अपने @ ट्रान्सएक्शन एट्रिब्यूट्स के साथ क्या होता है, इस बारे में चिंतित हूं, क्या मुझे सबक्लास से कॉल किए जाने पर वास्तव में लेन-देन का उपयोग करने की आवश्यकता पर भरोसा है, जब सबक्लास के पास कक्षा डिफ़ॉल्ट के रूप में NOT_SUPPORTED है?

उत्तर

21

जावा एनोटेशन विरासत में नहीं हैं, लेकिन जावाईई चश्मा इन गुणों को अपेक्षित काम करने की अनुमति देने के लिए नियमों को बदलते हैं। सामान्य एनोटेशन 1.1 spec देखें। धारा 2.1 भी उदाहरण के रूप में @TransactionAttribute का उपयोग करता है। ईजेबी 3.1 सेक्शन 13.3.7.1 स्पष्ट रूप से @ ट्रान्सएक्शन एट्रिब्यूट के नियमों को भी बताता है:

यदि बीन क्लास में सुपरक्लास हैं, तो निम्नलिखित अतिरिक्त नियम लागू होते हैं। एक वर्ग के स्तर के लेन-देन विशेषता एस पर तय नहीं है तो

  • लेनदेन विशेषता एक सुपर क्लास एस पर निर्दिष्ट एस द्वारा परिभाषित व्यापार के तरीकों पर लागू होता है, यह एस
  • पर TransactionAttribute (आवश्यक) के विनिर्देश के बराबर है
  • विधि एस के लिए ओवरराइड करने के लिए कक्षा एस द्वारा परिभाषित व्यावसायिक विधि एम पर एक लेनदेन विशेषता निर्दिष्ट की जा सकती है। लेन एस विशेषताएँ मूल्य स्पष्ट रूप से या स्पष्ट रूप से वर्ग एस
  • पर निर्दिष्ट किया गया है यदि कक्षा एस की विधि एम द्वारा परिभाषित एक व्यावसायिक विधि को ओवरराइड करता है एस का एक सुपरक्लास, एम की लेनदेन विशेषता उपरोक्त नियमों द्वारा निर्धारित की जाती है जैसा वर्ग एस
  • पर लागू होता है

संक्षेप में, सबसे JavaEE एनोटेशन के लिए, विधि-स्तर वाले एनोटेशन विधि पर लागू होते हैं एक उपवर्ग विधि ओवरराइड करता है, और कक्षा स्तर के एनोटेशन सभी तरीकों केवल उस वर्ग में परिभाषित करने के लिए लागू होते हैं। नियम "घटक-परिभाषित" वर्ग-स्तरीय एनोटेशन पर लागू नहीं होता है, जैसे कि @ स्टेटलेस (ईजेबी 3.1 विनिर्देश अनुभाग 4.9.2.1 देखें)

संबंधित मुद्दे