PersistenceContext kérdés...

Fórumok

Üdv,

van egy ilyen EJB3 session beanem:

@Stateless
public class BookBean implements BookBeanRemote, BookBeanLocal {
@PersistenceContext(unitName="WebBookCatalog")
EntityManager em;

public void addBook(Book book) {
em.persist(book);
}

public void removeBook(Book book) {
em.remove(book);
}

}

A probléma, hogy az addBook meghívására NullPointerException-t kapok. Néztem sok-sok példát a perzisztencia kontextus annotálására, meg EntityManagerFactory-val is próbáltam, de az meg nem tetszett a Hibernate-nek. Azt írta, hogy a jelenleg használt tranzakciós stratégiához hozzá kell férni a JTA-hoz. Egyelőre a JTA-t még nem ismerem, mert most tanulom a dolgokat, de nem lesznek túl bonyolult lekérdezések, szóval nem kell nekem bonyolult tranzakciókezelés. Ha segítetek, azt nagyon köszönöm, de pls. hagyjuk ki a szokásos JPA provider meg AS flame-et. Köszi!

Hozzászólások

van WebBookCatalog nevu persistent unit?
Ervenyes pool-ra mutat?

Igen, a persitence unit megvan a persistence.xml-ben:


<?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="WebBookCatalog">
	    <jta-data-source>java:PostgresDS</jta-data-source>
		<class>entity.webbookcatalog.PrintedBook</class>
		<class>entity.webbookcatalog.Person</class>
		<class>entity.webbookcatalog.Location</class>
		<class>entity.webbookcatalog.Lang</class>
		<class>entity.webbookcatalog.Genre</class>
		<class>entity.webbookcatalog.EBook</class>
		<class>entity.webbookcatalog.Book</class>
		<class>entity.webbookcatalog.Attachment</class>
	   <properties>
       </properties>
	</persistence-unit>
</persistence>

A pool-on a data source-ot érted? Elvileg az is be van állítva rendesen, induláskor nem is ír rá hibát a JBoss:


<datasources>
  <local-tx-datasource>
    <jndi-name>PostgresDS</jndi-name>
    <connection-url>jdbc:postgresql://127.0.0.1:5432/webbookcatalog</connection-url>
    <driver-class>org.postgresql.Driver</driver-class>
    <user-name>postgres</user-name>
    <password>foobar</password>
        <!-- sql to call when connection is created.  Can be anything, select 1 is valid for PostgreSQL
        <new-connection-sql>select 1</new-connection-sql>
        -->

        <!-- sql to call on an existing pooled connection when it is obtained from pool.  Can be anything, select 1 is valid for PostgreSQL
        <check-valid-connection-sql>select 1</check-valid-connection-sql>
        -->

      <!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml (optional) -->
      <metadata>
         <type-mapping>PostgreSQL 8.0</type-mapping>
      </metadata>
  </local-tx-datasource>

</datasources>

hacsak egy persistence-unitod van, akkor a contextet nem kell megnevezni amibol az EM -t akarod injektalni (bar ez AS fuggo, nem irtad, mit hasznalsz).

a provider classt definialnod kell, ahogy mar fent is irtak, nalam ez epp "
org.eclipse.persistence.jpa.PersistenceProvider", nyilvan a hibernatenel mas, ird bele azt.

a JTAt igazabol kezzel nem fogod hasznalni, azt majd elintezi neked a kontener, hacsak nem BMT -t hasznalsz.

Az session beanben a metodusokat hogy hivod meg, milyen kornyezetben? Hol es hogy peldanyositod a bean-t?

Van egy JSP, amin egy form van, ez hívja a szervletet:


<form action="AddBookServlet">
<table>
	<tr>
		<td>Title:</td>
		<td><input type="text" name="title" /></td>
	</tr>
	<tr>
		<td>Edition:</td>
		<td><input type="text" name="edition" /></td>
	</tr>

	<tr>
		<td colspan="2"><input type="submit" value="OK" /></td>
	</tr>
</table>
</form>

A szervletben pedig a doGet() és doPost() metódusokból hívom a közös feldolgozó processRequest()-et, itt példányosítom a beant:


public class AddBookServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	private BookBeanLocal bookBean;
       
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
         
        String title = request.getParameter("title");
        Short edition = Short.parseShort(request.getParameter("edition"));
                
        String result="Book successfully created";

        Book book = new PrintedBook();
        bookBean = new BookBean();
        
        book.setTitle(title);
        book.setEdition(edition);
        
        bookBean.addBook(book);
        
        request.setAttribute("addBookResult", result);
        request.getRequestDispatcher("addBook.jsp").forward(request, response); 
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}

}

Uhh, köszönöm, valóban nem volt ott...
Most már tovább jutok, viszont most valami tranzakciós hiba történik:
http://hup.pastebin.com/m5de943dc

Egy rövidebb entitást írok példának, ugyanúgy kezelem a JSP-ből meg a szervletből ezeket is, csak a könyves sokkal hosszabb és tulajdonképpen ott is pont ugyanez történik:


@Entity
public class Genre implements Serializable {
	private static final long serialVersionUID = 1L;
	@Id
	private String name;
	private String desc;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getDesc() {
		return desc;
	}
	public void setDesc(String desc) {
		this.desc = desc;
	}

}

Erre valami ötlet esetleg, hogy mitől lehet?

Köszi, legalább már tudom, hogy nem a kóddal van a baj. Azóta még próbálkoztam másik JDBC driverrel, de csak szarabb lett, már nem is fut normálisan a JBoss, meg a Glassfish se. Érik már ezen a gépen egy Windows reinstall azt hiszem...
A sörözéses Java EE jól hangzik. :) Most 5 kredites választható tárgyként tanulom, ahhoz kell ez a házi is, de majd ha lesz több időm, csinálom a SAI-t is megint.

Na, kísérleteztem vele sokat, most jelenleg a datasource-ot behúzza rendesen hiba nélkül. Látszik, hogy az SQL dialect is rendben van:


12:39:20,046 INFO  [InjectedDataSourceConnectionProvider] Using provided datasource
12:39:20,562 INFO  [SettingsFactory] RDBMS: PostgreSQL, version: 8.3.7
12:39:20,593 INFO  [SettingsFactory] JDBC driver: PostgreSQL Native Driver, version: PostgreSQL 8.3 JDBC2 with NO SSL (build 603)
12:39:20,640 INFO  [Dialect] Using dialect: org.hibernate.dialect.PostgreSQLDialect
12:39:20,656 INFO  [TransactionFactoryFactory] Transaction strategy: org.hibernate.ejb.transaction.JoinableCMTTransactionFactory
12:39:20,656 INFO  [TransactionManagerLookupFactory] instantiating TransactionManagerLookup: org.hibernate.transaction.JBossTransactionManagerLookup
12:39:20,671 INFO  [TransactionManagerLookupFactory] instantiated TransactionManagerLookup

Viszont mégis fennáll a hiba. Megpróbáltam a beaneket felannotálni NEVER tranzakció típusra, hogy elkerüljem a tranzakciók nyűgjeit, akkor pedig egy olyan kivételt kapok, amely azt mondja, hogy az EntityManager-t tranzakción belül kell elérni.

Köszönöm a sok segítséget, megoldódott végre a probléma! A desc foglalt szó, ezért fel kellett annotálni egy @Column-nal.

Más környezetek elől nem zárkózom el, de a JBoss-ra azért esett a választás, mert bizonyítottan fut rendesen FreeBSD alatt, a Hibernate meg ugye default JBoss alatt. A Glassfish egyébként Windowson nekem szarakodott, a NetBeans-szel együtt telepítve sem ment normálisan, külön meg a megadott módon futtatva a "telepítő" jar-t, NullPointerException-nel lehal.