2013-08-02 20 views
12

Bence bu problem daha da artar çünkü EJB'lerle bir şey elde edemedim. Varlığım için @Stateless olan bir hizmet sınıfım var. Benim oturum kapsamı sunum modelimde @EJB ile enjekte ederek kullanıyorum, her şey yolunda. "Kullanıcıların = service.findAllUsers();" yürütme üzerindeJava Sınıfında EJB'yi enjekte ederken NullPointerException

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

Ben pozisyonda bir NullPointerException olsun: Ama şimdi benim sunum modelinde kullanılmak üzere üzerine sahip datamodel bu EJB servisini kullanmak istedi Aynı eser, benim sunum modelinde bu datamodel üzerine yazdığınızda:

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

bu normal bir Java sınıfı bir EJB enjekte etmek mümkün değil midir? Ne yapmalıyım Sunum modelinde DataModel'i tanımlamak zorunda değilim?

Teşekkür

+0

BeanInterface'inizi EJB açıklamalarına dahil etmeye çalışın. Aynı problemi birkaç kez önce çözdüm ve düzeltdim. @EJB (beanInterface = YourInterface.class) ' – ZeusNet

cevap

13

EJB'ler yalnızca yönetilen fasulye enjekte edilir. Bir fasulye, JSF'nin kendi @ManagedBean, CDI's @Named, vb. Yoluyla bazı enjeksiyon kapları tarafından yönetildiğinde yönetilir. Bir EJB'yi başka bir EJB'ye bile enjekte edebilirsiniz. Bir EJB'yi yönetilmeyen bir sınıfa enjekte edemezsiniz (ancak JNDI'den elle kapatabilirsiniz, ancak bu çok çirkindir).

ettin temelde aşağıdaki seçenekler: yönetilen fasulye @PostConstruct yılında

  1. , sen argüman olarak geçmesi sonucunu sayede datamodel inşa (bu ListDataModel iş gibi de ne kadar standart veri modelleri olduğuna dikkat edin) . Eğer sonuç girmesini ister sayede


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

    LazyUserDataModel soyut olun.
    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(); 
    
    } 
    

    böylece anonim sınıf az
  3. lazyUsers = new LazyUserDataModel() { 
        @Override 
        public List<User> findAllUsers() { 
         return service.findAllUsers(); 
        } 
    }; 
    
    yanı LazyUserDataModel yönetilen bir fasulye yapın ve yerine enjekte acıyor.

    @Inject 
    private LazyUserDataModel lazyUsers; 
    

  4. ile

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

    Eğer düşündüm olarak böyle bir fullfledged anonim örneğini oluşturun.Eğer tüm kayıtları sağlamak bu sayede beton sorununa


    İlgisiz

, bir LazyDataModel sahip anlamı yok. Amacımız, mevcut belleğe bağlı duruma bağlı olarak SQL güçlerini ( LIMIT, OFFSET ve arkadaşları) kullanarak yalnızca bir altkümeyi veya kaydı talep etme olanağı sunmasıdır, böylece Java'nın belleğinde binlerce kayıt olmasa bile yüzlerce olması gerekmez. sadece on ya da öylesine. Başka bir deyişle, load() yönteminin hiçbir zaman first ve/veya pageSize argümanını kullanmıyorsanız, büyük ihtimalle tamamen yanlış bir şekilde yaklaşıyorsunuz demektir.

+0

Bu ayrıntılı yanıt için teşekkürler @BalusC. Bunu denemeden önce, iki kapalı konuya: LazyDataModel'in bu şekilde bir anlam ifade etmediğini biliyorum. Sadece kodu olabildiğince basitleştirmek istedim. Ama gerçekten anlamadığım ilk ifadeniz: Ne kurucunun hizmet etmesi gerekir? "Public UserPM()" de mi? Eğer bir şeyi gözden kaçırmamış olsaydım, işte tam olarak benim için böyle çalışır. – timmornYE

+0

Enjekte edilen bağımlılıklar, yalnızca örnekte oluşturulmadan önce örnek değişkenlerin ayarlanamaması nedeniyle basit nedenlerden dolayı, yalnızca 'PostConstruct' içinde değil, yalnızca konstrüktör olarak kullanılabilir. – BalusC

+0

Çözüm 4 benim için en güzel görünüyor ve çalışıyor! Teşekkürler! – timmornYE

2

Yalnızca konteyner tarafından oluşturulur fasulye ve EJB'ler içindeki fasulye ve EJB'ler enjekte edebilir. Kendinizi new kullanarak başlattığınız nesnelerin içinde değil. Kap, başlattığınız nesnelerden habersizdir ve bu nedenle bu nesnelerde herhangi bir şey enjekte edemez.

Yani, sadece konteyner örneğini izin vermedi ve LazyUserDataModel nesne enjekte:

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

    ... 
} 
İlgili konular