EJB 3.0 + Persistence API (grundsätzliche Fragen)

Cullen

Grünschnabel
Hallo zusammen,

ich hätte da ein paar grundsätzliche Fragen, an denen meine Bemühungen mich in Java EE 5 einzuarbeiten bereits mühevoll gestalten.

1.)
Lt. einer Literatur ist es auch möglich EntityBeans für einen DB-Zugriff auch für eine reine Java-Applikations, also ohne einen Applikationsserver wie JBoss, zu erstellen. Aber wie mach ich das. bzw. muss ich dazu auch die Beans in ein jar-File verpacken und wohin muss ich dieses dann deployen? (btw: Dieses Fachbuch benutzt dazu das Hibernate-Framework)

2.)
Die eigentliche Applikation, die ich zu erstellen habe, greift auf eine MaxDB bzw. SAPDB zu. Kann mir irgendjemand sagen, wie die Einträge in der persistence.xml zu lauten haben? Habe bisher im Internet noch so gut wie nichts aussagekräftiges dazu gefunden?

Hoffe, es kann mir jemand von euch helfen

VG

Cullen
 
Hallo,

um die JPA für eine lokale Anwendung zu nutzen, brauchst du einen Persistence-Provider (Hibernate, TopLink etc). Dann musst du dir eine persistence.xml schreiben, die ungefähr so aussieht.

Beispiel TopLink mit HSQLDB
XML:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	version="1.0">
	<persistence-unit name="example" transaction-type="RESOURCE_LOCAL">
		<class>de.tutorials.jpa.Teilnehmer2</class>
		<properties>
			<property name="toplink.jdbc.driver"
				value="org.hsqldb.jdbcDriver" />
			<property name="toplink.jdbc.url"
				value="jdbc:hsqldb:file:test" />
			<property name="toplink.jdbc.user" value="sa"/>
		</properties>
	</persistence-unit>
</persistence>

Diese muss im META-INF-Verzeichnis in deinem Projekt liegen.

Gespeichert werden die Beans so.

Java:
package de.tutorials.jpa;

import javax.persistence.EntityManager;
import javax.persistence.Persistence;

public class SimpleJPALocal {

	public static void main(String[] args) {
		
		
		EntityManager em = Persistence.createEntityManagerFactory("Scott").createEntityManager();
		Teilnehmer2 teilnehmer2 = new Teilnehmer2();
		teilnehmer2.setNachricht("Ich bin ein Datensatz");
		teilnehmer2.setName("Schirra");
		teilnehmer2.setKurs("EJB 3.0");
		
		em.getTransaction().begin();
		em.persist(teilnehmer2);
		
		em.getTransaction().commit();
		em.close();

	}
}

Und so könnte die Bean aussehen.

Java:
package de.tutorials.jpa;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Teilnehmer2 implements Serializable {
	@Id
	private String id;

	private String kurs;

	private String name;

	private String nachricht;

	private static final long serialVersionUID = 1L;

	public Teilnehmer2() {
		super();
	}

	public String getId() {
		return this.id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getKurs() {
		return this.kurs;
	}

	public void setKurs(String kurs) {
		this.kurs = kurs;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getNachricht() {
		return this.nachricht;
	}

	public void setNachricht(String nachricht) {
		this.nachricht = nachricht;
	}

}


Die Einträge in der Persistence.xml hängen auch von dem Persistence-Provider ab.

So würde das ganze mit Hibernate und HSQLDB aussehen.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	version="1.0">
	<persistence-unit name="example" transaction-type="RESOURCE_LOCAL">
		<class>de.tutorials.jpa.Teilnehmer2</class>
		<properties>
                        <property name="hibernate.dialect" 
                                value="org.hibernate.dialect.HSQLDialect"/>
			<property name="hibernate.connection.driver_class"
				value="org.hsqldb.jdbcDriver" />
			<property name="hibernate.connection.url"
				value="jdbc:hsqldb:file:test" />
			<property name="hibernate.connection.username" value="sa"/>
		</properties>
	</persistence-unit>
</persistence>


Für deine Datenbanken, musst du nur noch den JDBC-Treiber eintragen, die URL, den Nutzennamen und das Passwort.

Ich hoffe das hilft dir.

MFG

zEriX
 
Zuletzt bearbeitet von einem Moderator:
Hi und danke dir für deine Antwort.

Prinzipiell habe ich das Konzept mit den Entity- und Session-Beans schon verstanden und das erste Beispiel lokal auch zum Laufen bekommen. (mit dieser HSQLDB).

Mein aktuelles Problem ist, dass ich eine existierende MaxDB ansprechen muss und die Beans auf einen JBoss deployt werden sollen. Ich habe dazu eine Entity-Bean für die Tabelle angelegt die wie folgt aussieht.
Code:
package de.fhzw.portal.bean;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name="fv_firma")
@SequenceGenerator(name="fv_firma_sequence" , sequenceName="sq_fv_firma")
@NamedQuery(name = "FvFirma.findAll", query = "select o from FvFirma o")
public class FvFirma implements Serializable {
  private Integer fid;
  private String fname;
  private String str;
  private String stadtname;

  protected FvFirma() {
    super();
  }
  
  public FvFirma(Integer fid, String fname, String str, String stadtname) {
    super();
    this.fid = fid;
    this.fname = fname;
    this.str = str;
    this.stadtname = stadtname;
  }

  @Override
  public String toString() {
    return "FvFirma: " +getFid() + " Name: " + getFname() + " Straße: " +getStr() +
          " Stadt: " +getStadtname();
  }
   
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "fv_firma_sequence")
  public Integer getFid() {
    return fid;
  }

  public void setFid(Integer fid) {
    this.fid = fid;
  }

  @Column
  public void setFname(String fname) {
    this.fname = fname;
  }

  public String getFname() {
    return fname;
  }

  @Column
  public void setStr(String str) {
    this.str = str;
  }

  public String getStr() {
    return str;
  }

  @Column
  public void setStadtname(String stadtname) {
    this.stadtname = stadtname;
  }

  public String getStadtname() {
    return stadtname;
  }
}

Desweiteren habe ich für die Stateless Session Bean 2 Interfaces für lokal und remote sowie die dazugehörende Klasse erstellt

Code:
@Stateless
public class FvFirmaTestbean implements FvFirmaTestbeanLocal, 
                                        FvFirmaTestbeanRemote {

  @PersistenceContext
  EntityManager em;
  
  public static final String RemoteJNDIName = FvFirmaTestbean.class.getSimpleName() + "/remote";
  public static final String LocalJNDIName = FvFirmaTestbean.class.getSimpleName() + "/local";
  
  public void test() {
    
    System.out.println("A list of some companies");
    List someCompanies = em.createQuery("from Fv_Firma f where f.stadtname=:stadt").setParameter("stadt", "Hamburg").getResultList();
    for(Iterator it = someCompanies.iterator(); it.hasNext();){
      FvFirma element = (FvFirma) it.next();
      System.out.println(element);
    }
    System.out.println("A list of all companies");
    List allCompanies = em.createQuery("from Fv_Firma").getResultList();
    
    for(Iterator it = allCompanies.iterator(); it.hasNext();) {
      FvFirma element = (FvFirma) it.next();
    }
  }
}

Der Client soll nix anderes machen, als über Remote die Methode "test()" aufzurufen

Code:
public class FvFirmaClient {

  public static void main(String[] args) {
  
    Context context;
    try {
      context = new InitialContext();
      FvFirmaTestbeanRemote beanRemote = (FvFirmaTestbeanRemote) context.lookup(FvFirmaTestbean.RemoteJNDIName);
      beanRemote.test();
    }
    catch(NamingException e) {
      e.printStackTrace();
    }
  }
}

Zuguter Letzt habe die Beans auf den JBoss deployt (und der hat nicht mal gemeckert, welch Wunder ;-) ) Wenn ich nun aber den Client ausführe kommt folgende Exception

javax.naming.CommunicationException [Root exception is java.lang.ClassNotFoundException: org.jboss.ejb3.JBossProxy (no security manager: RMI class loader disabled)]
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:728)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:587)
at javax.naming.InitialContext.lookup(InitialContext.java:351)
at de.fhzw.portal.client.FvFirmaClient.main(FvFirmaClient.java:19)
Caused by: java.lang.ClassNotFoundException: org.jboss.ejb3.JBossProxy (no security manager: RMI class loader disabled)
at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:531)
at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:628)
at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:294)
at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:238)
at java.io_ObjectInputStream.readProxyDesc(ObjectInputStream.java:1494)
at java.io_ObjectInputStream.readClassDesc(ObjectInputStream.java:1457)
at java.io_ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1693)
at java.io_ObjectInputStream.readObject0(ObjectInputStream.java:1299)
at java.io_ObjectInputStream.readObject(ObjectInputStream.java:339)
at java.rmi.MarshalledObject.get(MarshalledObject.java:135)
at org.jnp.interfaces.MarshalledValuePair.get(MarshalledValuePair.java:72)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:652)

Hat jemand nen Plan, was ich da schon wieder falsch mache? :confused:

Danke schon mal vorab

Cullen
 
Im moment habe ich nicht so viel Zeit, kann aber später nochmal danach schauen.
Damit es mit deiner DB funktioniert, musst du nur den JDBC-Treiber deiner DB eintragen, die URL, Username und PW. Dann müsste es funktionieren mit deiner DB.
Wenn es auf JBoss laufen soll, dann läuft das ganze ja auch "nicht" lokal, also jetzt auf die JPA bezogen.

MFG

zEriX
 

Neue Beiträge

Zurück