2010-01-07 12 views
12

Ich habe eine statusfreie EJB, die auf meine Datenbank zugreift. Ich brauche diese Bean in einem JSF 2-Konverter, um ein Entity-Objekt vom String-Wert-Parameter zu retreive. Ich benutze JEE6 mit Glassfish V3.Injizieren Sie ein EJB in einen JSF-Konverter mit JEE6

@EJB Annotation funktioniert nicht und ruft eine NPE ab, weil sie sich im faces-Kontext befindet und keinen Zugriff auf den EJB-Kontext hat.

Meine Frage ist: Ist es immer noch möglich, diese Bean mit einer @Resource oder andere Annotation, oder eine JNDI-Lookup, oder brauche ich eine Abhilfe?


Lösung

einen JNDI-Lookup wie folgt tun:

try { 
    ic = new InitialContext(); 
    myejb= (MyEJB) ic 
    .lookup("java:global/xxxx/MyEJB"); 
    } catch (NamingException e) { 
    e.printStackTrace(); 
    } 

Antwort

6

I JSF nie 2.0 (nur 1.0) verwendet, aber Kapitel 5.4 der Spezifikation sagt:

[...] dem Container erlauben, Referenzen auf Container-verwaltete Ressourcen zu injizieren in eine verwaltete Bean-Instanz, bevor sie für die JSF-Anwendung zugänglich gemacht wird. Nur Bohnen, die in der Anfrage, Sitzung oder Anwendungsbereich Gültigkeitsbereich sind für Ressourceninjektion.

Aber bisher verstehe ich, ein JNDI-Lookup den Trick tun sollten.

+0

JNDI-Suche funktioniert nicht. Ich probierte @EJB (mappedName = "java: global/myProject/myEJB"), wobei der Wert derjenige ist, den glassfish in der Konsole als "portabler JNDI-Name" meines EJB ausgibt, während –

+2

keine @ EJB-Annotation verwendet. Rufen Sie die Zielkomponente mit InitialContext ab. – Bozho

+0

@Bozho: InitialContext hat funktioniert! :) Danke –

2

Andere (noch nicht so hübsche) Lösung kann binding statt converterId verwenden. JSF Mit Managed Beans nur:

< f: Wandler Bindung = "# {app.personConverter}"/>

Wo appBean für etwas steht wie: @ManagedBean(name="app") @ApplicationScoped class AppBean { @EJB private PersonService ps; private Converter personConverter; }

Es kann eine schönere Lösung in CDI sein -Stil (JSR-299), aber ich habe gescheitert diese ein Rennen zu machen:

< f: Wandler Bindung = "# {cdiBean}"/>

Wo cidBean sollte sein: @Named class CdiBean implements Converter { @EJB ... }

schlägt mit 'Standardverhalten erfordert einen Konverter-ID in dem Konstruktor übergeben aufgerufen'

Wie auch immer ersten Ansatz Bindung und App JSF Bean scoped arbeitet.

2

ich weiß nicht, ob diese Lösung recht ist ...aber es funktioniert:

@ManagedBean 
public class AcquisitionConverter implements Converter 
{ 
    @EJB 
    private AcquisitionService service; 

    @Override 
    public Object getAsObject(FacesContext context, UIComponent component, String value) 
    { 
     ... 
    } 

    @Override 
    public String getAsString(FacesContext context, UIComponent component, Object value) 
    { 
     ... 
    } 
} 

und

<h:inputText value="#{flowController.acquisition}" converter="#{acquisitionConverter}"> 

mit JSF 2.1.3 (mojarra) und Glasfischen 3.1.1

+0

Die '@ FacesConverter' Annotation ist in diesem Konstrukt übrigens überflüssig (und nur für Starter verwirrend). Entfernen Sie es. – BalusC

+0

ok, ich entfernte es :) –

+0

der Konverter = "# {acquisitionConverter}" war die Dinge, die nicht für mich arbeiten –

Verwandte Themen