2010-03-01 4 views
1

Je suis nouveau à Java EE. J'ai essayé de faire tourner quelques premiers exemples (JPA). J'utilise Glassfish v3. Le problème est que je n'obtiens pas l'App Server en injectant l'EntityManager. Hear est un exemple http://www.adam-bien.com/roller/abien/entry/ejb_3_persistence_jpa_for que j'ai étendu avec un client JSP.Glassfish JPA: Problèmes d'injection EntityManager

Entité:


package beans; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 

@Entity 
public class Book { 

    @Id 
    @GeneratedValue 
    private Long id; 
    private String title; 
    private String subtitle; 

    public Book() { 
    } 

    public Book(String title) { 
     this.title = title; 
    } 
} 

Bookservice Interface:


package beans; 
import javax.ejb.Local; 

@Local 
public interface BookService { 
    Book createOrUpdate(Book book); 
    void remove(Book book); 
    Book find(Object id); 
} 

BookServiceBean:


package beans; 
import javax.ejb.Stateless; 
import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 

@Stateless 
public class BookServiceBean implements BookService { 

    @PersistenceContext 
    private EntityManager em; 

    public Book createOrUpdate(Book book) { 
     return em.merge(book); 
    } 
    public void remove(Book book) { 
     em.remove(em.merge(book)); 
    } 
    public Book find(Object id) { 
     return em.find(Book.class, id); 
    } 
} 

persistence.xml:

<persistence> 
    <persistence-unit name="sample" transaction-type="JTA"> 
    <jta-data-source>jdbc/MarcelsDataSource</jta-data-source> 
    <properties> 
     <property name="eclipselink.ddl-generation" value="create-tables"/> 
    </properties> 
</persistence-unit> 
</persistence> 

index.jsp:

<%@ page import="beans.BookServiceBean" %> 
<%@ page import="beans.Book" %> 
<html> 
<body> 
<% 
    BookServiceBean bs = new BookServiceBean(); 
    Book b = new Book("Superman"); 
    bs.createOrUpdate(b); 
%> 
</body> 
</html> 

Si je lance l'exemple que je reçois un java.lang.NullPointerException dans la méthode createOrUpdate() de sorte que le entityManager est évidemment pas correctement injecté. J'ai essayé de trouver un remède pendant des jours et de l'aide serait très appréciée.

Merci

Marcel

+0

Y a-t-il aussi un problème avec le fait qu'il utilise l'état dans un EJB @Stateless? – cdmckay

Répondre

10

Vous obtenez un NullPointerException parce que vous instanciez votre BookService avec un new() - ce qui est fondamentalement faux - et rien ne s'injecte dans l'EJB. Les EJB sont des composants qui sont gérés par le conteneur et doivent être obtenus soit par injection, soit avec une recherche. Ici, alors que la spécification JSP autorise l'exécution de n'importe quel code dans un scriplet, l'appel d'un EJB à partir d'une JSP n'est en réalité pas vraiment encouragé et les JSP ne prennent pas en charge l'injection. En d'autres termes, vous devez utiliser une recherche:

<%@ page import="beans.BookService" %> 
<%@ page import="beans.Book" %> 
<html> 
<body> 
<% 
    BookService bs = (BookService) new InitialContext().lookup("java:module/BookServiceBean") 
    Book b = new Book("Superman"); 
    bs.createOrUpdate(b); 
%> 
</body> 
</html> 

Mais vous devriez appeler votre EJB à partir d'un Servlet ou un JSF Managed Bean (et votre EJB pourrait être injecté dans ces composants).

Si vous avez besoin de quelques échantillons, jetez un oeil à la Java EE Code Samples & Apps.

Mise à jour: Voir How do I access a Local EJB component from a POJO? dans la FAQ EJB pour plus de détails sur JNDI (en particulier la nouvelle portable global JNDI names defined by the EJB 3.1 specification).

+0

Merci beaucoup. Très bonne explication. Je reçois: javax.naming.NameNotFoundException: BookServiceBean pas trouvé ??? –

+0

@Marcel Je n'étais pas totalement sûr du nom JNDI sous lequel le bean serait disponible. Regardez la console GlassFish, le nom JDNI doit être connecté là-bas. –

+0

Cela a fonctionné comme ceci: InitialContext(). Lookup ("java: module/BookServiceBean"); Merci encore. Salutations –

1

Essayez:

@PersistenceContext(unitName = "sample") 
private EntityManager em; 
+1

Cela n'aidera pas tant qu'il utilise le constructeur. – whiskeysierra

+0

Merci. Je l'ai déjà changé et il ne semble pas être le problème –

0

Vous sont directement instancié avec la fève de service, lorsque vous avez vraiment besoin d'être avec le récipient injectent (via @EJB). Cependant, ceci n'est pas supporté dans une JSP, donc vous devrez aussi passer à une servlet.

+0

Merci beaucoup. Si j'utilise @EJB dans une servlet, j'obtiens une erreur de compilation: L'annotation @EJB n'est pas autorisée pour cet emplacement.MMMMMMMMM Marcel –

+0

Pourriez-vous donner un petit exemple? désolé je suis un novice –

+0

Ok. Il doit être en dehors des méthodes maintenant je reçois une très belle exception: –

Questions connexes