# Kein Zugriff auf Persistence Unit



## Sisyphus (28. Okt 2006)

Hi,

ich bin gerade dabei mich in JEE 5 einzuarbeiten, und bin dabei auf ein kleines Problem gestoßen.
Ich habe ein EJB Packet, in dem die Persitence Entities, die Beschreibung zur Persistence Unit und
eine Stateful Session Bean liegen. In der Bean versuche ich mit dem EntityManager auf Daten zuzugreifen.

Ausserdem habe ich noch eine Web Applikation in der eine JSP liegt. Der Web App hab ich das JAR-File der
EJB gegeben und  in der JSP versuche ich auf die Bean zuzugreifen. Das Problem ist jetzt, dass in der Bean
der EntityManager nicht gesetzt werden kann.

Die PersistenceUnit:

```
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="TestPU" transaction-type="JTA">
    <provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>
    <jta-data-source>Test_DataSource</jta-data-source>
    <properties>
      <property name="toplink.ddl-generation" value="create-tables"/>
    </properties>
  </persistence-unit>
</persistence>
```

Die EJB:

```
@Stateful
public class UserAgentBean implements UserAgentRemote, UserAgentLocal {

    @PersistenceContext(unitName="TestPU")
    private EntityManager em;
    private Student student;
    
    public UserAgentBean() {
    }

   public Student setStudent(int id) {
      student = em.find(Student.class, id);
   }
}
```

Die JSP Seite:

```
<html>
    <head>
        <title>JSP Page</title>
    </head>
    <body>
    
    <jsp:useBean id="userAgent" scope="session" class="ejb.UserAgentBean"/>
    <%
        userAgent.setStudent(123);
    %>
    
    </body>
</html>
```

Beim ausführen der JSP Seite bekomme ich folgenden StackTrace:

```
java.lang.NullPointerException
	ejb.UserAgentBean.setStudent(UserAgentBean.java:46)
	org.apache.jsp.index_jsp._jspService(index_jsp.java:80)
	org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:111)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:353)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:409)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:317)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
	com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:73)
	com.sun.enterprise.web.VirtualServerPipeline.invoke(VirtualServerPipeline.java:120)
	org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:231)
	com.sun.enterprise.web.connector.grizzly.ProcessorTask.invokeAdapter(ProcessorTask.java:667)
	com.sun.enterprise.web.connector.grizzly.ProcessorTask.processNonBlocked(ProcessorTask.java:574)
	com.sun.enterprise.web.connector.grizzly.ProcessorTask.process(ProcessorTask.java:844)
	com.sun.enterprise.web.connector.grizzly.ReadTask.executeProcessorTask(ReadTask.java:287)
	com.sun.enterprise.web.connector.grizzly.ReadTask.doTask(ReadTask.java:212)
	com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:252)
	com.sun.enterprise.web.connector.grizzly.WorkerThread.run(WorkerThread.java:75)
```

Beim Debuggen ist zu erkennen, dass der EntityManager null ist.
Das eigenartige ist, dass wenn ich in der WebApplikation ein Servlet anlege, kann ich Problemlos mit der Bean und dem EM arbeiten.

Das Servlet:

```
public class UserAgentTestServlet extends HttpServlet {
    
    @EJB UserAgentRemote userAgent;
    
    /** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        out.println("<html>");
        out.println("<head>");
        out.println("</head>");
        out.println("<body>");
        
        userAgent.setStudent(1);

        out.println("</body>");
        out.println("</html>");

        out.close();
    }
    ...
```

Da ich noch nicht lange mit dem JEE 5 arbeite, bin ich etwas ratlos. Ich hab schon alle möglichen Kombinationen in der JSP ausprobiert.
Hab auch versucht die Persitence Klassen in eine eigene JAR zu packen, und so weiter. Leider bin ich jetzt ziemlich am Ende meines Lateins  :bahnhof: 

Hat hier vielleicht jemand einen Tipp?

Danke, 
Sisyphus

P.S.:
Achja, ich verwende den Sun Application Server 9, falls das relevant ist  ???:L


----------



## SlaterB (28. Okt 2006)

die Frameworks bei denen man nie weiß was sie tun..,

im Servlet setzt du das Bean mit 
@EJB UserAgentRemote userAgent; 

wird irgendwo noch new Bean() aufgerufen oder geschieht auch das automatisch?

der JSP-Code sieht ja eher danach aus, als wenn da new Bean() ganz ohne irgendwelche Automatismen durchgeführt wird

schreibe evtl. eine im Servlet korrekt erzeugte Bean in den SessionScope?


----------



## Sisyphus (28. Okt 2006)

SlaterB hat gesagt.:
			
		

> die Frameworks bei denen man nie weiß was sie tun..,


Ich dachte, das ist so beabsichtigt? Zumidest wird es von Sun als Feature dargestellt  :roll: 
Ich wollte mich erstmal mit der Basis beschäftigen (und die verstehen) bevor ich irgendein
aufgesetztes Framework anfange. 

Ich rufe nirgendwo explizit new Bean() auf, ich nehme an, dass durch die @EJB Annotation 
über JNDI die Entsprechende Bean gesucht wird und der Container legt mir dann eine an.

Deshalb bin ich auch davon ausgeganben, dass der JSP Code

```
<jsp:useBean ...
```
genauso funktioniert.



			
				SlaterB hat gesagt.:
			
		

> schreibe evtl. eine im Servlet korrekt erzeugte Bean in den SessionScope?


Danke für den Tipp, da habe ich jetzt einen Ansatzpunkt, von dem aus ich mal weiterprobieren kann   
Ich melde mich wieder, wenn ich das Problem so lösen konnte (oder wieder stecken bleibe).


----------



## Sisyphus (29. Okt 2006)

Nochmal vielen Dank an SlaterB!  :applaus:  :applaus:  :applaus: 

Ich habe das ganze jetzt so gelöst:

In der JSP Seite:

```
<jsp:include page="SetUserAgent" />
<jsp:useBean id="userAgent" scope="session" type="UserAgentRemote"/>
<%
        userAgent.setStudent(123);
%>
```

Und das Servlet dazu sieht folgendermaßen aus:

```
public class SetUserAgent extends HttpServlet {
    @EJB UserAgentRemote userAgent;
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        if(request.getSession().getAttribute("userAgent") == null) {
            request.getSession().setAttribute("userAgent", userAgent);
        }
    }
}
```

Kann mir jetzt noch jemand sagen, ob die Stateful EJB die ich über die Annotation im Servlet bekomme
für die Session eindeutig ist. Also wenn mehrere User die JSP Seite aufrufen, bekommt dann jeder eine
eigene Bean in die Session?

Edit:
Achja, und kann mir jemand ein gutes Buch zu JavaServer Faces empfehlen (bevorzugt auf deutsch, muss aber nicht sein)


----------



## SlaterB (29. Okt 2006)

ich glaube eher, dass es von den Servlet-Objeken nicht viele gibt,
und diese für beliebige Sessions benutzt werden,
daher dürften allle Sessions das gleiche Bean haben oder zumindest jeweils eins aus einer kleinen Menge,

aber ob das was ich irgendwann mal über Servlets gelernt habe noch stimmt?
zum Glück ist es recht einfach sowas nachzuprüfen,

überschreibe einfach den Konstruktor des Beans und lasse dir ausgeben,
wann ein Bean erzeugt wird,
logge jeden Request, jede Session 
(ganz primitiv: schaue ob ein Feld 'nummer' gesetzt ist, ansonsten vergebe eine eindeutige Nummer),
dann ein paar Sessions erzeugen, dürfte jeweils eine neue geben wenn InternetExplorer geschlossen und neu geöffnet wird,
usw.,
alles ausprobieren, nicht nur fragen und nachlesen


----------

