2013-08-02 9 views
12

में ईजेबी इंजेक्शन करते समय NullPointerException मुझे लगता है कि यह समस्या बढ़ जाती है क्योंकि मुझे ईजेबी के साथ कुछ नहीं मिला। मेरे पास मेरी इकाई के लिए एक सेवा वर्ग है, जो @ स्टेटलेस है। जब मैं अपने सत्र स्कोप्ड प्रेजेंटेशन मॉडल में @EJB के साथ इंजेक्शन करके इसका उपयोग करता हूं, तो सब ठीक है। लेकिन अब मैं इस EJB सेवा एक डेटामॉडल में मैं अपनी प्रस्तुति मॉडल में इस्तेमाल के लिए ओवरराइट है उपयोग करना चाहता था:जावा क्लास

public class LazyUserDataModel extends LazyDataModel<User> { 

    @EJB 
    private UserService service; 

    @Override 
    public List<User> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map filters) { 
     List<User> users; 
     users= service.findAllUsers(); 
     this.setRowCount(users.size()); 
     return users; 
    } 
} 

निष्पादन पर मैं स्थान पर एक NullPointerException मिल "उन = service.findAllUsers();" एक ही काम करता है, जब मैं अपनी प्रस्तुति मॉडल में इस डेटामॉडल के ऊपर लिख:

@Named 
@SessionScoped 
public class UserPM { 
    @EJB 
    private UserService service; 

    private LazyDataModel<User> lazyUsers; 

    public UserPM() { 

      // Don't works 
      //lazyUsers = new LazyUserDataModel(); 

      lazyUsers = new LazyDataModel() { 
      @Override 
       public List<User> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map filters) { 
        List<User> users; 
        users = service.findAllUsers(); 
        this.setRowCount(users .size()); 
        return users ; 
       } 
     }; 
    } 
} 

नहीं यह एक सामान्य जावा क्लास में एक EJB सुई संभव है? मुझे क्या करना चाहिए कि मुझे प्रस्तुति मॉडल में डेटामोडेल को परिभाषित करने की आवश्यकता नहीं है?

धन्यवाद

+0

अपने बीन इंटरफेस को ईजेबी एनोटेशन में डालने का प्रयास करें। मुझे कुछ बार पहले एक ही समस्या है और यह तय है। '@EJB (बीनइंटरफेस = YourInterface.class)' – ZeusNet

उत्तर

13

EJBs केवल प्रबंधित सेम में इंजेक्ट किया जाता। एक बीन प्रबंधित होता है जब इसे कुछ इंजेक्शन कंटेनर द्वारा प्रबंधित किया जाता है, जैसे कि जेएसएफ के अपने @ManagedBean, सीडीआई के @Named, आदि के माध्यम से आप किसी अन्य ईजेबी में ईजेबी इंजेक्ट भी कर सकते हैं। आप एक अप्रबंधित वर्ग में ईजेबी इंजेक्ट नहीं कर सकते हैं (हालांकि आप इसे मैन्युअल रूप से जेएनडीआई से पकड़ सकते हैं, लेकिन यह सादा बदसूरत है)।

आपने मूल रूप से निम्नलिखित विकल्पों:

  1. अपने प्रबंधित सेम के @PostConstruct में, डेटामॉडल निर्माण जिससे आप तर्क के रूप में परिणाम पारित (ध्यान दें कि यह कैसे मानक डेटा मॉडल है ListDataModel काम की तरह) ।

    @PostConstruct 
    public void init() { 
        lazyUsers = new LazyUserDataModel(service.findAllUsers()); 
    } 
    

  2. LazyUserDataModel सार बनाओ जिससे आप परिणाम प्रदान करने के लिए कहें।

    public abstract class LazyUserDataModel extends LazyDataModel<User> { 
    
        @Override 
        public List<User> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map filters) { 
         List<User> users; 
         users = findAllUsers(); 
         this.setRowCount(users.size()); 
         return users ; 
        } 
    
        public abstract List<User> findAllUsers(); 
    
    } 
    

    ताकि गुमनाम वर्ग दर्द होता है कम

    lazyUsers = new LazyUserDataModel() { 
        @Override 
        public List<User> findAllUsers() { 
         return service.findAllUsers(); 
        } 
    }; 
    

  3. LazyUserDataModel एक प्रबंधित सेम के साथ-साथ करते हैं और बजाय इसे इंजेक्षन।

    @Named @RequestScoped 
    public class LazyUserDataModel extends LazyDataModel<User> { 
        // ... 
    } 
    

    @Inject 
    private LazyUserDataModel lazyUsers; 
    

  4. साथ

    की तरह के रूप में आप लगा एक पूर्ण गुमनाम उदाहरण बनाएँ।


असंबंधित ठोस समस्या को, वहाँ एक LazyDataModel होने का कोई बात है जिसके तहत आप सभी रिकॉर्ड प्रदान करते हैं। इसका इरादा यह है कि यह आपको वर्तमान पगनेटेड स्थिति के आधार पर एसक्यूएल शक्तियों (LIMIT, OFFSET और दोस्तों) का उपयोग करके केवल एक सबसेट या रिकॉर्ड का अनुरोध करने की संभावना प्रदान करता है ताकि जावा की स्मृति में हजारों रिकॉर्ड न होने पर आपको सैकड़ों होने की आवश्यकता न हो, केवल दस या तो। दूसरे शब्दों में, यदि आप first और/या pageSizeload() विधि के तर्क का कभी भी उपयोग नहीं कर रहे हैं, तो संभवतः आप इसे पूरी तरह गलत तरीके से देख रहे हैं।

+0

इस विस्तृत उत्तर @ बाल्लूसी के लिए धन्यवाद। इससे पहले कि मैं इसे दो विषयों से दूर करने की कोशिश करता हूं: मुझे पता है कि LazyDataModel इस तरह से कोई समझ नहीं आता है। मैं केवल जितना संभव हो सके कोड को सरल बनाना चाहता था। लेकिन जो मैं वास्तव में समझ में नहीं आता वह आपका पहला बयान है: किस कन्स्ट्रक्टर में सेवा शून्य होनी चाहिए? "सार्वजनिक उपयोगकर्ता पीएम()" में? अगर मैंने कुछ अनदेखा नहीं किया है तो यह ठीक है कि यह मेरे लिए कैसे काम करता है। – timmornYE

+0

इंजेक्शन निर्भरता कन्स्ट्रक्टर में उपलब्ध नहीं है, लेकिन सरल कारण के लिए केवल '@ पोस्टकॉन्स्ट्रक्चर' में, उदाहरण के पहले आवृत्ति चर सेट नहीं किया जा सकता है। – BalusC

+0

समाधान 4 मेरे लिए सबसे अच्छा और काम करता है! धन्यवाद! – timmornYE

2

आप केवल सेम और सेम और EJBs कंटेनर द्वारा बनाई गई हैं कि अंदर EJBs इंजेक्षन कर सकते हैं। ऑब्जेक्ट्स के अंदर नहीं जो आप new का उपयोग करके स्वयं को तत्काल बनाते हैं। कंटेनर उन वस्तुओं से अनजान है जिन्हें आप तुरंत चालू करते हैं, और इस प्रकार इन वस्तुओं में कुछ भी इंजेक्ट करने में असमर्थ हैं।

तो, बस कंटेनर इन्स्तांत जाने और LazyUserDataModel वस्तु इंजेक्षन:

@Named 
@SessionScoped 
public class UserPM { 
    @Inject 
    private LazyUserDataModel lazyUsers; 

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