Hibernate mehrere @oneToone

Generic1

Top Contributor
Hallo,

ich glaub ich hab noch ein spezielles Problem.
Ich habe eine Tabelle TParticipant und eine Tabelle TContact und zwischen diesen Tabellen besteht eine OneToOne- Beziehung, wobei sich die Primary keys der Tabellen referenzieren. Das klappt alles sehr gut. So schaut der Generator aus, der dafür sorgt, dass der Primary key von TParticipant auch in TContact verwendet wird:

Java:
@Entity
@SuppressWarnings("serial")
@Table(name="TParticipant")
public class Participant implements Serializable {

  private Integer pk_part;
  private String firstname;
  private String surname;
  private String chipnumber;
  private Contact contact;
  private Paid paid;
  
  public Participant() {}

@Id
  @GeneratedValue(generator="foreign")
  @GenericGenerator(name="foreign", strategy = "foreign", parameters={
     @Parameter(name="property", value="contact")  // die id von dieser Entity wir auch in Contact eingetragen
      })
  public Integer getPk_part() {
    return pk_part;
    }
...

Jetzt hat aber die Tabelle TParticipant nicht nur eine OneToOne Beziehung zu TContact, sondern auch eine zu TPaid, also ich bräuchte ein weiteres property -> paid,
jetzt hab ichs schon so versucht:

Java:
@Id
  @GeneratedValue(generator="foreign")
  @GenericGenerator(name="foreign", strategy = "foreign", parameters={
     @Parameter(name="property", value="contact"),
     @Parameter(name="property", value="paid")  // hier noch eine weitere Referenz
      })
  public Integer getPk_part() {
    return pk_part;
    }

Das funktioniert aber leider nicht, es wird nur das 2. property aktiv (in diesem Fall paid), das erste bleibt null.

Weiß jemand wie ich das machen kann bzw. ob das irgenwie funktioniert und wie?
Besten Dank.
lg
 
hmmm das check ich nicht. in welcher klasse soll das sein?

@Id
@GeneratedValue(generator="foreign")
@GenericGenerator(name="foreign", strategy = "foreign", parameters={
@Parameter(name="property", value="contact"),
@Parameter(name="property", value="paid") // hier noch eine weitere Referenz
})
public Integer getPk_part() {
return pk_part;
}

Ich habs jetzt so gelöst:
hibernate.cfg.xml; Tabellen werden automatisch durch Hibernate erstellt. also nix selber create table mit SQL..
dieses Ding <property name="hibernate.hbm2ddl.auto">update</property> erstellt in meiner Datenbank "filme" die Tabellen automatisch
Java:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/filme</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.connection.pool_size">10</property>

<property name="show_sql">true</property>
<property name="hibernate.format_sql">false</property>

<property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.hbm2ddl.auto">update</property>

<!-- Mapping-Dateien Klassen caseSensitive-->

<mapping class="a1.spring.hibernate.buch.Adresse" />  
<mapping class="a1.spring.hibernate.buch.Person" />
<mapping class="a1.spring.hibernate.buch.Adresse" />
<mapping class="a1.spring.hibernate.buch.Herz" />     

</session-factory>
</hibernate-configuration>

Ich habe Person, Adresse und neue Tabelle Herz.
Die 2 anderen Tabellen Person und Adresse habe ich schon hier gepostet http://www.java-forum.org/data-tier/99897-hibernate-1-n-1-1-a.html

die neue Tabelle Herz:

Java:
package a1.spring.hibernate.buch;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;

@Entity
@Table(name="herz")
public class Herz {
	
	public Herz(){
	
	}
	
	private Integer id;
	private String name;
	private Person person;
	
	
	@Id @GeneratedValue(generator="foreign")
	  @GenericGenerator(name="foreign", strategy = "foreign", parameters={
	    @Parameter(name="property", value="person")
	  })

	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	@Column(name="name")
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@OneToOne(cascade=CascadeType.ALL)
	@PrimaryKeyJoinColumn
	public Person getPerson() {
		return person;
	}
	public void setPerson(Person person) {
		this.person = person;
	}
	

}

hier rennt das Zeug:
Java:
	private static void perad(Session session, Transaction transaction) {
		Adresse a=new Adresse();
		Person p=new Person();
		Herz herz=new Herz();
		herz.setName("Du hast 3 Herzen");
		
		p.setName("Dreier");
		a.setAdresse("Strasse33333");
		//p.setAdresse(a);
		a.setPerson(p);
		herz.setPerson(p);
		//p.setAdresse(a);
		
		session.save(herz);
		
		session.save(p);
		session.save(a);
		transaction.commit();
		session.close();
		System.exit(0);
		
	}


Person:
id, name
1, Max
2, Obdachlos
3, Dreier
4, Roboter

Adresse:
id, adresse
1, strasse1
3, strasse333
roboter nix adresse

Es gibt kein 2, weil Obdachlos keine Adresse hat und da einfach a.setPerson(p); auskommentiert war

Herz,
1, Herz1
2, Herz2
3, Herz3
roboter nix herz

//session.save(herz);
session.save(p);
//session.save(a);
bei Roboter wurde nur "person" gespeicht, deswegen auch nur der Eintrag in person table und herz und a(dresse) verworfen.
 
Dem Post fehlen konkrete Informationen zum Problem. Stacktrace oder Sourcecode.

Wenn ich das richtig deute möchtest du TParticipient(osä) speichern, und er Meckert dass einer der Einträge "TPaid" oder "TContract" auf null verweisen ohne dass ein SQL-Statement ausgeführt wird, also komplett Java-Seitig?

Ich schätze mal du musst bei der 1:1 referenz mitgeben dass die abhängigen Objekte mitgespeichert/geändert werden sollen wenn sie nicht schon existieren. Also Dass zuerst der Patricipient, der Contract und dann der Paid gespeichert werden soll. Quasi wie ein Wasserfall (eine Cascade).

Lösungsvorschlag:
Füge der @OneToOne-Annotation das Wasserfallprinzip(cascade=CascadeType.ALL) hinzu, wie es Java.getSkills() beschrieben hatte.

Mögliche andere Probleme:
Sollte datenbankseitig TParticipient nicht nur auf TContract sondern ein zweiter ForeginKey von TContract auf TParticipient bestehen: kommt hibernate MÄCHTIG durcheinander.
 
Zuletzt bearbeitet:

Neue Themen


Zurück
Oben