hibernate/jpa abgefragte Listen immer mit Null-Werten gefüllt

thommy.s

Aktives Mitglied
Hallo alle miteinander,

ich möchte (nebenbei gesagt über einen WebService) Applikationen die Möglichkeit bieten, durch parametrisierte Methodenaufrufe bestimmte Dtanbak-Abfragen vorzunehmen und als Array zurückzubekommen. Hier die Klasse:

Java:
/**
 * 
 */
package org.medfak.thommys.CFL.action.netpoint;

import java.util.List;

import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.jboss.seam.annotations.Name;
import org.medfak.thommys.CFL.model.Raum;
import org.medfak.thommys.CFL.model.pdfplan.ScheduleValues;


@Stateless
@WebService
@SOAPBinding(style = Style.RPC)
@Name("net")
public class ReturnResultListsBean implements ReturnResultListsRemote {
	
	private String str1;
	
	@PersistenceContext(unitName="CFL")
	private EntityManager em;	
	
	
	Raum[] rsArr;
	
	
	private List<Raum> raumList;
	
		
	private List<ScheduleValues> rsList;
			
	
	@SuppressWarnings("unchecked")
	@WebMethod(operationName = "getResult")
	//@Factory("rsArr")
	public Raum[] getStundenplanResult(Integer studiengangId, Integer persgroupId, Integer kategorieId, Integer studienjahrId, Integer modulId, Integer einrichtungId) {
		
						
		raumList = (List<Raum>) em.createQuery("select r from Raum r").getResultList();
				
		rsArr = new Raum[raumList.size()];			
		
		
		
		for (int i = 0; i < raumList.size(); i++) {
									
			rsArr[i] = raumList.get(i);
			
			System.out.println(raumList.get(i).getId().getDtxt());
			
		}

		
		System.out.println("Arraygröße = " + rsArr.length);
		
				
		return rsArr;
		
	}
	
	
}

Ich versuche also, zunächst eine Liste 'List<Raum> raumList' zu bekommen und wandle sie zur besseren Übergabe in ein Array um.
Hier noch der (automatisch erzeugte) Quellcode der Entity Beans:

Java:
package org.medfak.thommys.CFL.model;
// Generated 01.03.2011 15:02:09 by Hibernate Tools 3.2.4.GA

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.PersistenceUnit;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.hibernate.validator.NotNull;

/**
 * Raum generated by hbm2java
 */
@SuppressWarnings("serial")
@Entity
@Table(name = "raum", uniqueConstraints = @UniqueConstraint(columnNames = "rgid"))
@PersistenceUnit(unitName="CFL")
public class Raum implements java.io.Serializable {

	private RaumId id;

	public Raum() {
		
		System.out.println("Bin in der Raum-Klasse");
	}

	public Raum(RaumId id) {
		
		System.out.println("Bin in der Raum-Klasse");
		
		this.id = id;
	}

	@EmbeddedId
	@AttributeOverrides({
			@AttributeOverride(name = "rgid", column = @Column(name = "rgid", unique = true, nullable = false)),
			@AttributeOverride(name = "aikz", column = @Column(name = "aikz", length = 1)),
			@AttributeOverride(name = "ktxt", column = @Column(name = "ktxt", length = 10)),
			@AttributeOverride(name = "dtxt", column = @Column(name = "dtxt")),
			@AttributeOverride(name = "ltxt", column = @Column(name = "ltxt")),
			@AttributeOverride(name = "gebid", column = @Column(name = "gebid")),
			@AttributeOverride(name = "eid", column = @Column(name = "eid")),
			@AttributeOverride(name = "raumart", column = @Column(name = "raumart", length = 10)),
			@AttributeOverride(name = "kostenst", column = @Column(name = "kostenst", length = 20)),
			@AttributeOverride(name = "raumartid", column = @Column(name = "raumartid")),
			@AttributeOverride(name = "raumnr", column = @Column(name = "raumnr", length = 8)),
			@AttributeOverride(name = "zeitstempel", column = @Column(name = "zeitstempel", length = 29)),
			@AttributeOverride(name = "geschossnummer", column = @Column(name = "geschossnummer", length = 25)),
			@AttributeOverride(name = "stockwerkid", column = @Column(name = "stockwerkid")),
			@AttributeOverride(name = "bemerkung", column = @Column(name = "bemerkung")),
			@AttributeOverride(name = "externid", column = @Column(name = "externid", length = 32))})
	@NotNull
	public RaumId getId() {
		
		System.out.println("Bin in der Raum-Klasse");
		
		return this.id;
	}

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

}

und die 'eingebettete'

Java:
package org.medfak.thommys.CFL.model;
// Generated 01.03.2011 15:02:09 by Hibernate Tools 3.2.4.GA

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Embeddable;

import org.hibernate.validator.Length;

/**
 * RaumId generated by hbm2java
 */
@SuppressWarnings("serial")
@Embeddable
public class RaumId implements java.io.Serializable {

	private int rgid;
	private Character aikz;
	private String ktxt;
	private String dtxt;
	private String ltxt;
	private Integer gebid;
	private Integer eid;
	private String raumart;
	private String kostenst;
	private Integer raumartid;
	private String raumnr;
	private Date zeitstempel;
	private String geschossnummer;
	private Integer stockwerkid;
	private String bemerkung;
	private String externid;

	public RaumId() {
	}

	public RaumId(int rgid) {
		
		
		
		this.rgid = rgid;
	}
	public RaumId(int rgid, Character aikz, String ktxt, String dtxt,
			String ltxt, Integer gebid, Integer eid, String raumart,
			String kostenst, Integer raumartid, String raumnr,
			Date zeitstempel, String geschossnummer, Integer stockwerkid,
			String bemerkung, String externid) {
		
		
				
		this.rgid = rgid;
		this.aikz = aikz;
		this.ktxt = ktxt;
		this.dtxt = dtxt;
		this.ltxt = ltxt;
		this.gebid = gebid;
		this.eid = eid;
		this.raumart = raumart;
		this.kostenst = kostenst;
		this.raumartid = raumartid;
		this.raumnr = raumnr;
		this.zeitstempel = zeitstempel;
		this.geschossnummer = geschossnummer;
		this.stockwerkid = stockwerkid;
		this.bemerkung = bemerkung;
		this.externid = externid;
	}

	@Column(name = "rgid", unique = true, nullable = false)
	public int getRgid() {
		return this.rgid;
	}

	public void setRgid(int rgid) {
		this.rgid = rgid;
	}

	@Column(name = "aikz", length = 1)
	public Character getAikz() {
		return this.aikz;
	}

	public void setAikz(Character aikz) {
		this.aikz = aikz;
	}

	@Column(name = "ktxt", length = 10)
	@Length(max = 10)
	public String getKtxt() {
		return this.ktxt;
	}

	public void setKtxt(String ktxt) {
		this.ktxt = ktxt;
	}

	@Column(name = "dtxt")
	public String getDtxt() {
		return this.dtxt;
	}

	public void setDtxt(String dtxt) {
		this.dtxt = dtxt;
	}

	@Column(name = "ltxt")
	public String getLtxt() {
		return this.ltxt;
	}

	public void setLtxt(String ltxt) {
		this.ltxt = ltxt;
	}

	@Column(name = "gebid")
	public Integer getGebid() {
		return this.gebid;
	}

	public void setGebid(Integer gebid) {
		this.gebid = gebid;
	}

	@Column(name = "eid")
	public Integer getEid() {
		return this.eid;
	}

	public void setEid(Integer eid) {
		this.eid = eid;
	}

	@Column(name = "raumart", length = 10)
	@Length(max = 10)
	public String getRaumart() {
		return this.raumart;
	}

	public void setRaumart(String raumart) {
		this.raumart = raumart;
	}

	@Column(name = "kostenst", length = 20)
	@Length(max = 20)
	public String getKostenst() {
		return this.kostenst;
	}

	public void setKostenst(String kostenst) {
		this.kostenst = kostenst;
	}

	@Column(name = "raumartid")
	public Integer getRaumartid() {
		return this.raumartid;
	}

	public void setRaumartid(Integer raumartid) {
		this.raumartid = raumartid;
	}

	@Column(name = "raumnr", length = 8)
	@Length(max = 8)
	public String getRaumnr() {
		return this.raumnr;
	}

	public void setRaumnr(String raumnr) {
		this.raumnr = raumnr;
	}

	@Column(name = "zeitstempel", length = 29)
	public Date getZeitstempel() {
		return this.zeitstempel;
	}

	public void setZeitstempel(Date zeitstempel) {
		this.zeitstempel = zeitstempel;
	}

	@Column(name = "geschossnummer", length = 25)
	@Length(max = 25)
	public String getGeschossnummer() {
		return this.geschossnummer;
	}

	public void setGeschossnummer(String geschossnummer) {
		this.geschossnummer = geschossnummer;
	}

	@Column(name = "stockwerkid")
	public Integer getStockwerkid() {
		return this.stockwerkid;
	}

	public void setStockwerkid(Integer stockwerkid) {
		this.stockwerkid = stockwerkid;
	}

	@Column(name = "bemerkung")
	public String getBemerkung() {
		return this.bemerkung;
	}

	public void setBemerkung(String bemerkung) {
		this.bemerkung = bemerkung;
	}

	@Column(name = "externid", length = 32)
	@Length(max = 32)
	public String getExternid() {
		return this.externid;
	}

	public void setExternid(String externid) {
		this.externid = externid;
	}

	public boolean equals(Object other) {
		if ((this == other))
			return true;
		if ((other == null))
			return false;
		if (!(other instanceof RaumId))
			return false;
		RaumId castOther = (RaumId) other;

		return (this.getRgid() == castOther.getRgid())
				&& ((this.getAikz() == castOther.getAikz()) || (this.getAikz() != null
						&& castOther.getAikz() != null && this.getAikz()
						.equals(castOther.getAikz())))
				&& ((this.getKtxt() == castOther.getKtxt()) || (this.getKtxt() != null
						&& castOther.getKtxt() != null && this.getKtxt()
						.equals(castOther.getKtxt())))
				&& ((this.getDtxt() == castOther.getDtxt()) || (this.getDtxt() != null
						&& castOther.getDtxt() != null && this.getDtxt()
						.equals(castOther.getDtxt())))
				&& ((this.getLtxt() == castOther.getLtxt()) || (this.getLtxt() != null
						&& castOther.getLtxt() != null && this.getLtxt()
						.equals(castOther.getLtxt())))
				&& ((this.getGebid() == castOther.getGebid()) || (this
						.getGebid() != null
						&& castOther.getGebid() != null && this.getGebid()
						.equals(castOther.getGebid())))
				&& ((this.getEid() == castOther.getEid()) || (this.getEid() != null
						&& castOther.getEid() != null && this.getEid().equals(
						castOther.getEid())))
				&& ((this.getRaumart() == castOther.getRaumart()) || (this
						.getRaumart() != null
						&& castOther.getRaumart() != null && this.getRaumart()
						.equals(castOther.getRaumart())))
				&& ((this.getKostenst() == castOther.getKostenst()) || (this
						.getKostenst() != null
						&& castOther.getKostenst() != null && this
						.getKostenst().equals(castOther.getKostenst())))
				&& ((this.getRaumartid() == castOther.getRaumartid()) || (this
						.getRaumartid() != null
						&& castOther.getRaumartid() != null && this
						.getRaumartid().equals(castOther.getRaumartid())))
				&& ((this.getRaumnr() == castOther.getRaumnr()) || (this
						.getRaumnr() != null
						&& castOther.getRaumnr() != null && this.getRaumnr()
						.equals(castOther.getRaumnr())))
				&& ((this.getZeitstempel() == castOther.getZeitstempel()) || (this
						.getZeitstempel() != null
						&& castOther.getZeitstempel() != null && this
						.getZeitstempel().equals(castOther.getZeitstempel())))
				&& ((this.getGeschossnummer() == castOther.getGeschossnummer()) || (this
						.getGeschossnummer() != null
						&& castOther.getGeschossnummer() != null && this
						.getGeschossnummer().equals(
								castOther.getGeschossnummer())))
				&& ((this.getStockwerkid() == castOther.getStockwerkid()) || (this
						.getStockwerkid() != null
						&& castOther.getStockwerkid() != null && this
						.getStockwerkid().equals(castOther.getStockwerkid())))
				&& ((this.getBemerkung() == castOther.getBemerkung()) || (this
						.getBemerkung() != null
						&& castOther.getBemerkung() != null && this
						.getBemerkung().equals(castOther.getBemerkung())))
				&& ((this.getExternid() == castOther.getExternid()) || (this
						.getExternid() != null
						&& castOther.getExternid() != null && this
						.getExternid().equals(castOther.getExternid())));
	}

	public int hashCode() {
		int result = 17;

		result = 37 * result + this.getRgid();
		result = 37 * result
				+ (getAikz() == null ? 0 : this.getAikz().hashCode());
		result = 37 * result
				+ (getKtxt() == null ? 0 : this.getKtxt().hashCode());
		result = 37 * result
				+ (getDtxt() == null ? 0 : this.getDtxt().hashCode());
		result = 37 * result
				+ (getLtxt() == null ? 0 : this.getLtxt().hashCode());
		result = 37 * result
				+ (getGebid() == null ? 0 : this.getGebid().hashCode());
		result = 37 * result
				+ (getEid() == null ? 0 : this.getEid().hashCode());
		result = 37 * result
				+ (getRaumart() == null ? 0 : this.getRaumart().hashCode());
		result = 37 * result
				+ (getKostenst() == null ? 0 : this.getKostenst().hashCode());
		result = 37 * result
				+ (getRaumartid() == null ? 0 : this.getRaumartid().hashCode());
		result = 37 * result
				+ (getRaumnr() == null ? 0 : this.getRaumnr().hashCode());
		result = 37
				* result
				+ (getZeitstempel() == null ? 0 : this.getZeitstempel()
						.hashCode());
		result = 37
				* result
				+ (getGeschossnummer() == null ? 0 : this.getGeschossnummer()
						.hashCode());
		result = 37
				* result
				+ (getStockwerkid() == null ? 0 : this.getStockwerkid()
						.hashCode());
		result = 37 * result
				+ (getBemerkung() == null ? 0 : this.getBemerkung().hashCode());
		result = 37 * result
				+ (getExternid() == null ? 0 : this.getExternid().hashCode());
		return result;
	}

}

Die Abfrage selbst muss wohl auch stattfinden, jedenfalls stimmt die Anzahl der Felder im Array exakt mit der Datensatzmenge überein. Problem ist nur, dass diese Felder nicht eine Instanz von 'Raum' enthalten, sondern NULL.

Was ich nun schon ausprobierte habe, würde mengenmäßig für mehrere Threads in diesem Forum reichen, ich weiß nun nicht mehr weiter.

Hat jemand irgendeinen heißen Tipp für mich....? Please help!!!

Viele Grüße

Thomas
 
was macht denn die Methode getStundenplanResult() genau?
du fragst dort von der DB eine Liste ab, funktioniert das? wie groß ist die Liste, was enthält sie?

in der Schleife zur Befüllung des Arrays steht
> System.out.println(raumList.get(i).getId().getDtxt());
erscheinen diese Ausgaben? sind also die Objekte in der Liste nicht null? wenn sie null wären müsste hier ja eine NullPointerException kommen,

falls die Methode normal läuft und du Zugriff auf die Ausgaben hast, prüfe ob am Ende das Array befüllt ist,
wenn anscheinend ja und an anderer Stelle dann doch nicht mehr, dann kann das Ursachen haben komplett unabhängig von all deinem geposteten Code

übe zunächst mit einem WebService ohne Datenbank, der auf Server-Seite ein Array mit drei Dummy-Objekten erzeugt,
kannst du diese erfolgreich übertragen?
fange mit 3 Strings an, später dann 3 neu erstellte Raumobjekte, danach an die Datenbank wagen wobei wie gesagt erstmal klären ob auf Serverseite der DB-Zugriff klappt
 
Hallo SlaterB,

der WebService ist nicht das Problem, der funktioniert. Auf der Client-Seite kommt das Array auch an, dort eben auch gefüllt mit Null-Werten.

Um deine Fragen der Reihe nach zu beantworten:

was macht denn die Methode getStundenplanResult() genau?
du fragst dort von der DB eine Liste ab, funktioniert das? wie groß ist die Liste, was enthält sie?

Die Methode soll eigentlich nur die von der Client-Seite mitgeschickten Parameter aufnehmen und das Antwort-Array an den Client zurückgeben. Wie oben schon erwähnt, funzt die Rückgabe. Die Parameter habe ich bisher links liegen gelassen, da schon die einfache Abfrage (ohne weitere Parameter) auf die Datenbank nicht funktioniert. Die Liste kommt zurück, enthält auch die exakte (88 Datensätze sind es) Zahl an Feldern, welche jedoch nur Null-Werte enthalten. Wie du schon richtig sagst, bekomm' ich für

Java:
> System.out.println(raumList.get(i).getId().getDtxt());

eine NullpointerException.

falls die Methode normal läuft und du Zugriff auf die Ausgaben hast, prüfe ob am Ende das Array befüllt ist,
wenn anscheinend ja und an anderer Stelle dann doch nicht mehr, dann kann das Ursachen haben komplett unabhängig von all deinem geposteten Code

wie gesagt, Zugriff habe ich keinen.

übe zunächst mit einem WebService ohne Datenbank, der auf Server-Seite ein Array mit drei Dummy-Objekten erzeugt,
kannst du diese erfolgreich übertragen?
fange mit 3 Strings an, später dann 3 neu erstellte Raumobjekte, danach an die Datenbank wagen wobei wie gesagt erstmal klären ob auf Serverseite der DB-Zugriff klappt

Das habe ich natürlich getan (den Teil mit der "Übungsmethode" habe ich weggelassen), mit Erfolg.

Es scheint (das habe ich vorhin verschwitzt mitzuteilen) so zu sein, das die Entity Beans gar nicht angesprochen werden. Mein Test

Java:
System.out.println("Bin in der Raum-Klasse");

führt zu keinerlei Ausgabe.

Viele Grüße

Thomas
 
eine Hibernate Rückgabe mit 88x null in einer Liste, wow, davon habe ich nun wirklich noch nicht gehört, falls nicht gerade speziell ein einzelnes Attribut abgefragt wird, welches in der DB null ist,

es gibt für HQL noch eine einfachere Syntax,
em.createQuery("from Raum")
funktioniert diese?

-----

was bei dir in Hibernate-Hinsicht nicht funktioniert kann ich persönlich leider nicht beantworten,
aber auch hier auf meine altbewährte Vereinfachungsstrategie hinweisen:
fange evtl. erstmal ein komplett neues Projekt an, fange mit einer Datenbanktabelle mit nur einem String-Attribut an,
dazu ein Java-Mapping (nicht automatisch generiert sondern selber anstrengen..) mit nur einem String-Attribut, passend auf Tabelle und DB-Attribut gemappt, evtl. getter/setter
kein Konstruktor, keine Id, besonders nicht so extrem kompliziert zusammengebaut, kein verrücktes equals & Co.,
keinen abgrundirrsinnigen Quatsch wie @AttributeOverrides, @PersistenceUnit(unitName="CFL") und was immer da irgendjemand ausgedacht hat

in die DB paar Einträge einfügen, mit Hibernate auslesen,
wenn die Hello World-ähnliche Grundlage funktioniert, darfst du danach gerne Schritt für Schritt wieder alles komplexer machen,
wahrscheinlich landest du bei denselbem Fehler, kannst dann aber neue Information beitragen wie 'es liegt an RaumId',
ich werde dabei aber wohl dann nicht weiterhelfen können
 
...um das vllt. noch zu präzisieren, jedes dieser 88 Felder enthält an sich jeweils ein Objekt der Klasse Raum, also von der Sache her schon mal richtig... Nur eben nix drin

Das Konglomerat mit der z.B. Raum-Klasse und RaumId-Klasse ist Hibernate geschuldet. In der gesamten Datenbank existiert nicht ein einziger Primärschlüssel, weshalb Hibernate sämtliche Attribute als PK betrachtet und diese in so eine Id-Klasse 'embedded' auslagert, die bisherige Anwendung hat alles über den Java-Code geregelt. Es für die Anwendung "von Hand" zu erstellen kommt aber nicht in Frage, da es sich insgesamt um fast 200 teilweise recht umfangreiche Tabellen handelt.

Und ich habe die Vermutung, dass hier in dem Konglomerat auch der Hund begraben liegt. Es ist nicht mein erster Versuch mit Hibernate, aber bei den vorangegangenen handelte es sich um "richtige" Tabellen mit PK.

Vllt. hast du recht, werd' mich mal an ein kleines Testprojekt machen und dort im Kleinen experimentieren. Wenn die ganzen möglichen Seiteneffekte ausgeschaltet sind, wird's vllt. klarer.

Problem ist, dass ich eigentlich etwas unter Zeitdruck stehe. Aber das müssen wir wohl durch....

sollte ich etwas herausfinden, werde ich auch hier berichten.

Trotzdem bin ich natürlich für weitere Tipps dankbar...


Grüße Thomas
 
also Raum-Objekte sind es schon, aber die Id darin ist jeweils null?
tja, kompliziertes Mapping, was da alles schiefgehen kann.., da kann ich nichts zu beitragen
 
Sorry es mal so auszudrücken aber deine Klasse Raumid ist voll kommender blödsinn!

Das hat erstmal nichts mit JPA sondern mit Grundlagen Datenbanken zu tun!

Ein Primär-Schlüssel sollte wenn möglich immer ein numerischer, ganzzahliger Wert sein! (Perfomance!) In Ausnahmefälle bedient man sich Zeichenketten!

Im Bereich der verteilten System verwendet man z.B. eine GUID d.h. einen zusammengesetzten Primär-Schlüssel aus
Long:id, String:System - um zu wissen wo der Datensatz erstellt wurde.

Ich denke du solltest dein Design überdenken und denn RaumId besitzt die Attribute die Raum benötigt dann musst du Dir überlegen wie der Primär-Schlüssel vergeben wird entweder von Dir selber oder automatisch!

Code:
@Entity
public class Raum{

@Id
@GeneratedValue
private Long id;

// weiter
}


Weiterhin hat @PersistenceUnit(unitName="CFL") in der Entity nichts zu suchen sondern wenn dann in der zugehörigen SessionBean!

Greetz
 
@JimPanse
... die Entity Beans wurden von Hibernate (automatisiert) erstellt, und zwar auf Basis einer bereits vorhandenen und in Betrieb befindlichen Datenbank, an der ich auch nichts ändern kann. Würde das Design wohl selbst anders gestaltet haben, aber es ist so wie es ist.
Die Entwickler der Anwendung (und der DB) haben sich davon wohl eine größere Flexibilität versprochen, kann es mir selbst auch nicht anders erklären...

Hibernate hat die Klassen so erzeugt, weil in der Tabelle (die ich nicht ändern kann) kein PK (wobei man 'rgid' erwartet hätte) existiert, deshalb alle Spalten in Gesamtheit als PK verwendet werden (zu sehen in der Erstellung von Klasse 'RaumId' mit sämtlichen Attributen).

Zu deinem zweiten Einwand (betreffs @PersitenceUnit) muss ich sagen, dass ich mir darüber nicht sicher war, da ich mehrere Datenquellen verwenden möchte (muss). Werde ihn beherzigen...



Vg Thomas
 
Zuletzt bearbeitet:
...nun, ich hab' das Problem nun so gelöst, dass ich in den Entity-Klassen ein Attribut zum Id-Attribut gemacht habe. somit klappt der Zugriff ganz easy
 

Neue Themen


Zurück
Oben