[Glassfish EJB] OneToMany geht nicht

damike

Mitglied
Hi

Ich hab Glassfish v3 final und hab folgendes Problem mit EclipseLink:

Java:
@Entity
public class Person implements Serializable
{
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;
	
	private String name;
	
	@OneToMany(mappedBy = "person", fetch = FetchType.EAGER)
	private List<Hobby> hobbys;

             // getter und setter
}

Java:
@Entity
public class Hobby
{
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;	
	
	private String name;
	
	@ManyToOne
	@JoinColumn
	private Person person;

              // getter und setter
}

Java:
@javax.ejb.Remote
public interface Testing
{
	public void addTestData();
	public List<Person> getTestData();
}

Java:
@javax.ejb.Stateless
public class TestingBean implements Testing
{
	@javax.persistence.PersistenceContext
	private EntityManager entityManager;
	
	public void addTestData()
	{
		Person p = new Person();
		p.setName("KARL");
		entityManager.persist(p);
		
		Hobby h1 = new Hobby();
		h1.setName("h1");
		h1.setPerson(p);
		
		entityManager.persist(h1);				
	}
	
	public List<Person> getTestData()
	{
		TypedQuery<Person> gridQuery = entityManager.createQuery("SELECT e FROM Person e", Person.class);
		return gridQuery.getResultList();
	}
}

Das Problem ist jetzt wenn ich mit getTestData am Client die Daten abfrage bekomm ich zwar "KARL" - aber die Hobbies nicht ... Das Eager Load greift nicht ...
Ich hab dann mit JOIN FETCH probiert - geht - aber ich bekomme die Ergebnisse durch das JOIN doppelt :S Verwende MySQL - die Daten werden in die Datenbank korrekt geschrieben ...

Weiß jemand was da falsch rennt?

Danke
LG
 
Zuletzt bearbeitet:
N

nillehammer

Gast
Du hast hier eine bidirektionale Relation definiert (Person kennt ihre Hobbies, Hobby kennt seine Person). Bei JPA bist Du selbst dafür verantwortlich, dass beide Enden korrekt sind. Adde beim Code für das Hobby noch folgende Zeile:
Java:
Hobby h1 = new Hobby();
h1.setName("h1");
h1.setPerson(p);
// Die Zeile hier ist neu
person.getHobbies.add(h1);
Da es recht nervig sein kann, daran immer zu denken, macht es Sinn, das Update der Enden in einer der Entities abzufrühstücken. Beispielsweise könnest Du einen Konstruktor für Hobby definieren, in dem Du die Person übergibst und im Konstruktor machst du dann das add.

Auch das getHobbies.add ist nicht aus zwei Gründen nicht so schön:
- Sieht einfach doof aus ;)
- Der getter gibt eine modifiable List zurück
Da wäre es gut, in Person eine public Methode addHobby anzubieten, den normalen getter getHobbies package private zu machen und einen public getter getUnmodifiableHobbies zu implementieren, der mit Collections.unmodifiableList eine unmodifiable List zurück gibt.

[EDIT]
Ups, Dein getter dürfte getHobbys heißen. Im Englischen ist die Mehrzahl korrekterweise hobbies, deswegen hab ich's falsch gemacht.
[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:

Sanix

Top Contributor
Kriegst du eine Exception beim Zugriff auf die Hobbies oder ist die Liste leer?

Duplicates kannst du versuchen mit
Code:
select DISTINCT p from person p
umgehen oder du verwendest ein Set für die Hobbies. Aber dein Problem scheint wo anders zu liegen.
 

damike

Mitglied
@nillehammer: das einfügen geht Problemlos. Die Daten sind meiner Meinung nach korrekt gesetzt:
Hobby hat eine Spalter PERSON_ID - die wird korrekt gesetzt

@Sanix: leere Liste. Sorry - da ich schon so viel probiert habe hab ich vergessen zu erwähnen dass

Exception Description: An attempt was made to traverse a relationship using indirection that had a null Session. This often occurs when a n entity with an uninstantiated LAZY relationship is serialized and that lazy relationship is traversed after serialization. To avoid this issue, ins tantiate the LAZY relationship prior to serialization.

fliegt. Aber warum LAZY wenn ich EAGER verwende?
 
N

nillehammer

Gast
This often occurs when a n entity with an uninstantiated LAZY relationship is serialized and that lazy relationship is traversed after serialization.
Das hat mich noch auf eine Idee gebracht. Hobby implementiert bei Dir gar nicht Serializable. Einen Versuch wäre es wert...
 

damike

Mitglied
Hab ich schon versucht - bringt nichts. Hab auch schon EAGER auch bei Hobbies gemacht

Ich bin echt am Verzweifeln mit dem Teil :-S
 

EasyEagle

Aktives Mitglied
Also ich hab meine @ManyToOne Annotations immer so geschrieben:

Java:
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="PERSON_ID")  //also der Spaltenname der Personenspalte in der Hobbytabelle
private Person person;

Vielleicht hilfts :)
 

Tente

Mitglied
Hi,

um die Verknüpfungen musst du dich in deiner Anwendung schon selbst kümmern.
Du sagst zwar
Java:
h1.setPerson(p);
, aber damit kennt das Hobby seine Person, aber die Liste der Hobbies in der Person muss ebenfalls geplegt werden! Also das Hobby manuell da über
Java:
p.getHobbies.add(h1);
einpflegen. JPA aktualisiert die Referenzen nicht bei jedem Zugriff auf das Objekt. Wenn es im Cache ist (was es nach dem persist ist), dann holt es auch genau erstmal dieses Objekt und aktualisiert es nicht mit zusätzlichen Informationen. Wären ja für JPA "sinnlose" selects. Referenzen müssen gegenseitig bekannt gemacht werden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
thor_norsk Glassfish Server unter Windows startet nicht! Allgemeines EE 20
M Glassfish Deployment-Problem unter Eclipse Allgemeines EE 0
FINF_AW_Alex remote Glassfish Library unverträglichkeit Allgemeines EE 0
J JSF Glassfish jdbcRelam und Oracle-Datenbank - WEB9102: Web Login Failed Allgemeines EE 0
Yamanuchi Glassfish 4 : Client Anzahl restriktieren Allgemeines EE 2
N Glassfish 4 JDBC-Realm Authentifizierung Beispiel gesucht Allgemeines EE 7
C Komplettes Durcheinander / Locales OSX/Linux Glassfish Allgemeines EE 3
A Probleme bei der Einbindung eines Liferay Portalserver (Glassfish) Allgemeines EE 7
C Glassfish Custom Realm (oder wie auch immer man das löst) Allgemeines EE 5
H Bean läuft unter GlassFish, aber JBoss nicht Allgemeines EE 5
ruutaiokwu glassfish library konflikte vermeiden? Allgemeines EE 3
H Glassfish - Open Source Lizenz für den kommerziellen produktiven Einsatz? Allgemeines EE 2
S Glassfish: Deployment von Realms Allgemeines EE 2
L Eclipse (Helios); Glassfish 3; EJB und VirtualBox Allgemeines EE 1
F Java EE Server nutzung kostenlos an Schule? (zB. mit Glassfish) Allgemeines EE 6
T Auf GlassFish JDBC-Ressourcen zugreifen Allgemeines EE 4
T MS SQL Server, GlassFish, JDBC Allgemeines EE 2
M Fehler bei Javamail Session mit Glassfish 3 Allgemeines EE 3
M Problem mit Lookup auf EJB3 mit Glassfish Allgemeines EE 11
D Debug Modus im Glassfish 2.1 plötzlich nicht mehr möglich Allgemeines EE 2
D Glassfish 3 ohne Cluster Support? Allgemeines EE 1
musiKk Glassfish: Properties zur Laufzeit... wohin? Allgemeines EE 6
Semox Ist Glassfish auch ein Webserver? Allgemeines EE 26
K Glassfish Application Client Allgemeines EE 4
B Glassfish, Sjsas und wie sich das Teil noch nennt . . Allgemeines EE 8
B GlassFish & JAAS - Konfiguration für AppClient Allgemeines EE 1
H Hibernate - OneToMany - mappedBy reference an unknown target entity property Allgemeines EE 1
S JPA Entitys anlegen OneToMany Relation abbilden Allgemeines EE 10
N Spring Wie geht Dependency Injection + Google Guice? Allgemeines EE 5
S JEE installation geht nicht? Allgemeines EE 6
S JSF und CSS: background:url() geht nicht Allgemeines EE 2
S m2eclips + strust2 == geht nicht Allgemeines EE 5
A jsf: Servlet aufrufen, wie geht das? web.xml Fehler? Allgemeines EE 13
D Objekt geht bei request verloren Allgemeines EE 9
E Warum geht das nicht (EL Frage)? Allgemeines EE 3
L Zwei Browserfenster mit unterschiedlicher session - geht das Allgemeines EE 3
T Problem, Image-Button geht nur nicht im Internet Explorer Allgemeines EE 6
A Servlet/JSP Chat -> geht das? Allgemeines EE 10

Ähnliche Java Themen

Neue Themen


Oben