# Hibernate 1:n, 1:1



## Generic1 (6. Mai 2010)

Hallo,

ich steh gerade auf der Leitung, ich habe mir jetzt eine Applikation mit einer Hibernate- Anbindung mit unterstützung von Spring für eine Tabelle gemacht:

DaoMain:

```
public final class DaoMain {

    public static void main(String[] args) {
    
    final ApplicationContext ctx = new FileSystemXmlApplicationContext("src/service.xml");
    final HibernateParticipantDao dao = (HibernateParticipantDao) ctx.getBean("rantDao");
    final Participant rant = new Participant();
    rant.setName("Hans");
    rant.setSurname("Maier");
    dao.saveParticipant(rant);

    final List<Participant> participantList = dao.getAllParticipants();
    System.out.println("ParticipantList: " + participantList);
  }
}
```

HibernateParticipantDao:

```
public final class HibernateParticipantDao extends HibernateDaoSupport implements ParticipantDao {
   
   private static final String PARTICIPANTS = Participant.class.getName();

   public HibernateParticipantDao() {}


   public List<Participant> getAllParticipants() {
      return getHibernateTemplate().find("from " + PARTICIPANTS);
      }

   public void saveParticipant(final Participant participant) {
      getHibernateTemplate().saveOrUpdate(participant);
      }

   public List<Participant> getParticipantsForDay(Date day) {
      return getHibernateTemplate().find("from " + PARTICIPANTS + " where postedDate = ?", day);
      }
}
```

Wenn ich jetzt 2 Tabellen habe, z.B.: Participant und Adress, wie kann ich das dann im Code machen, damit diese 2 Tabellen bzw. auf Codeebene Objekte eine 1:1 Beziehung haben.
Vielen Dank,
lg


----------



## SlaterB (6. Mai 2010)

mach es doch so wie es in der Anleitung für 1:1 steht?


----------



## Java.getSkill() (6. Mai 2010)

Das musst du doch mit Annotations in den einzelnen Beans für die Tabellen machen?

hier ein link One to One Mapping


----------



## Generic1 (7. Mai 2010)

Muss leider noch mal um Hilfe bitten,
ich hab mir jetzt einiges durchgelesen, manche verwenden *.hbn Files für die Konfiguration, ich bräuchte aber unbedingt eine Lösung mit Annotations.
Ich steh da auf der Leitung, ich weiß dass ich eine @OneToOne(?) irgendwo einfügen muss, mir ist aber nicht klar wo -> was mir logisch erscheinen würde, wäre eine @OneToOne(?) beim Primary Key der Klasse Participant einzufügen, so in der Art:


```
@Id
  @OneToOne(??)
  @GeneratedValue(strategy=GenerationType.AUTO)
  public Integer getPk_part() {
    return pk_part;
    }
```

lieg ich da richtig und was muss man da in die Klammern schreiben -> wahrscheinlich die Referenz aber ich hab bis jetzt noch nichts gefunden, was mir da weiterhelfen würde?
Besten Dank für Hilfe!!
lg


PARTICIPANT- Klasse:

```
@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 int fk_club;
  private int fk_address;
  private int fk_born;
  private int fk_gender;
  
  public Participant() {}

  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  public Integer getPk_part() {
    return pk_part;
    }

  public void setPk_part(final Integer pk_part) {
    this.pk_part = pk_part;
    }
... getter und setter
```
Contact- Klasse

```
@Entity
@SuppressWarnings("serial")
@Table(name="TContact")
public class Contact implements Serializable {

    private Integer pk_contact;
    private String email;
    private String telnumber;
    private String fax;

    public Contact() {}

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    public Integer getPk_contact() {
        return pk_contact;
        }

    public void setPk_part(final Integer pk_contact) {
        this.pk_contact = pk_contact;
        }
... getter und setter
```


SQL- Code, wie ich die 2 Tabellen TParticipant und TContact erzeugt habe

```
CREATE TABLE TContact(pk_contact INT NOT NULL,
                      email VARCHAR(80),
                      telnumber VARCHAR(80),
                      fax VARCHAR(80),
                      PRIMARY KEY(pk_contact),
                      FOREIGN KEY(pk_contact) REFERENCES TParticipant(pk_part)
                     ) ENGINE = INNODB;

CREATE TABLE TParticipant(pk_part INT NOT NULL AUTO_INCREMENT,
                          firstname   VARCHAR(100) NOT NULL,
                          surname     VARCHAR(150) NOT NULL,
                          chipnumber  VARCHAR(8),
                          fk_club     INT,
                          fk_address  INT,
                          fk_born     INT,
                          fk_gender   INT,
                          UNIQUE (chipnumber),
                          PRIMARY KEY(pk_part),
			  FOREIGN KEY(fk_club)    REFERENCES TClub(pk_club),
			  FOREIGN KEY(fk_address) REFERENCES TAddress(pk_address),
			  FOREIGN KEY(fk_born)    REFERENCES TBorn(pk_born),
			  FOREIGN KEY(fk_gender)  REFERENCES TGender(pk_gender)
                          ) ENGINE = INNODB;
```


----------



## SlaterB (7. Mai 2010)

man mappt keine Integer-Ids, sondern direkt Objekte,
in Contact hättest du also

private Participant participant;
oder wierum auch immer

Hibernate Annotations
schon gelesen, besonders
2.2.5.1. One-to-one
?

ich persönlich kann dabei aber nicht weiterhelfen, verwende nur Mapping-XML-Dateien
(und ob ich dann weiter wüßte wäre auch noch ne Frage)


----------



## Generic1 (7. Mai 2010)

So, habs jetzt hinbekommen, 
Eine Frage hätte ich noch und zwar TParticipant und TContact haben ja eine 1:1 Relation,
der Primary key von TParticipant hat ein AUTO_INCREMENT, d.h. also ich müsste den Primary key von der Tabelle TParticipant irgendwie in erfahrung bringen können im Java- Code damit ich diesen dann mittels contact.setPk_contact(x); setzen kann.
Wie könnte ich das lösen?
Besten Dank!!
lg



```
CREATE TABLE TParticipant(pk_part INT NOT NULL AUTO_INCREMENT,
                          firstname   VARCHAR(100) NOT NULL,
                          surname     VARCHAR(150) NOT NULL,
                          PRIMARY KEY(pk_part)
                          ) ENGINE = INNODB;

CREATE TABLE TContact(pk_contact INT NOT NULL,
                      email VARCHAR(80),
                      PRIMARY KEY(pk_contact),
                      FOREIGN KEY(pk_contact) REFERENCES TParticipant(pk_part)
                     ) ENGINE = INNODB;
```



```
final Participant participant = new Participant();
    participant.setFirstname("Hans");
    participant.setSurname("Maier");
    participant.setChipnumber("DF-12345");
    final Contact contact = new Contact();
    contact.setPk_contact(16);  // diese ID muss ich erraten, damit Contact in die DB- Tabelle eingetragen wird
    contact.setEmail("hans.maier@web.de");
    contact.setTelnumber("0634534653");
    participant.setContact(contact);
    dao.saveParticipant(participant);
```


----------



## SlaterB (7. Mai 2010)

SlaterB hat gesagt.:


> man mappt keine Integer-Ids, sondern direkt Objekte,
> in Contact hättest du also
> 
> private Participant participant;
> oder wie rum auch immer



ansonsten sollte nach session.save() und session.flush() auch die Id im gespeicherten Objekt verfügbar sein


----------



## Generic1 (7. Mai 2010)

SlaterB hat gesagt.:


> man mappt keine Integer-Ids, sondern direkt Objekte,
> in Contact hättest du also
> 
> private Participant participant;
> oder wie rum auch immer



Das versteh ich jetzt nicht ganz, ich hab in der Entity Participant eine Referenz contact, als eh ein Object, was müsst ich da oben ändern -> muss ich da die Datenbank- Tabellen ändern (also die SQLs oben) oder muss ich da was im code ändern -> weiß jetzt nicht genau wie ich das Auflösen kann?


```
@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;
```


----------



## SlaterB (7. Mai 2010)

du musst dir schon ein vollständiges Tutorial anschauen,
wie sehen Beispiel-Tabellen und das Mapping dazu aus, das geht auch mit hbm, das Prinzip sieht man daran

im zuletzt genannten Link steht ja schon einiges, von den DB-Tabellen abgesehen, obwohl immerhin mit Hinweisen wie
@PrimaryKeyJoinColumn
was ganz nach deinem Beispiel klingt
oder auch
@JoinColumn(name="passport_fk")

ganz grob gesucht hier noch was
Chapter 1. Tutorial

1.2.2. A unidirectional Set-based association
zeigt zwei Klassen verknüpft und weiter unten 'The database schema for this mapping is therefore:'

allgemein kann und will ich das hier aber nicht alles im Detail erklären


----------



## Generic1 (7. Mai 2010)

Das hätt ich mir alles angesehen und habs auch so gemacht (unten), ich hab aber keine Ahnung warums nicht klappt. Ich komm einfach nicht drauf, weiß noch jemand etwas dazu?
Vielen Dank,
lg


```
public final class DaoMain {

    public static void main(String[] args) {
    
    final ApplicationContext ctx = new FileSystemXmlApplicationContext("src/service.xml");
    final HibernateParticipantDao dao = (HibernateParticipantDao) ctx.getBean("participantDao");
    final Participant participant = new Participant();
    participant.setFirstname("Hans");
    participant.setSurname("Maier");
    //participant.setChipnumber("DF-12345");
    final Contact contact = new Contact();
    contact.setEmail("hans.mair@web.de");
    contact.setTelnumber("0664/534508697");
    participant.setContact(contact); 
    dao.saveParticipant(participant);

    final List<Participant> participantList = dao.getAllParticipants();
    System.out.println("ParticipantList: " + participantList);
  }
}
```


```
@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;
  
  public Participant() {}

  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  public Integer getPk_part() {
    return pk_part;
    }

  public void setPk_part(final Integer pk_part) {
    this.pk_part = pk_part;
    }

  @OneToOne(cascade = CascadeType.ALL)
  @PrimaryKeyJoinColumn
  public Contact getContact() {
    return contact;
    }

  public void setContact(final Contact contact) {
    this.contact = contact;
    }   
...
```


```
@Entity
@SuppressWarnings("serial")
@Table(name="TContact")
public class Contact implements Serializable {

    @Id
    private Integer pk_contact;
    private String email;
    private String telnumber;
    private String fax;

    public Contact() {}

    public Integer getPk_contact() {
        return pk_contact;
        }

    public void setPk_contact(final Integer pk_contact) {
        this.pk_contact = pk_contact;
        }
```


----------



## SlaterB (7. Mai 2010)

was klappt denn nicht?


----------



## Generic1 (7. Mai 2010)

Ich bekomm den Fehler:


```
ids for this class must be manually assigned before calling save(): at.eventtiming.domain.Contact; nested exception is
org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save():
at.eventtiming.domain.Contact
```

wenn ichs so mach wie unten, dann klappts aber dann muss ich 2 mal speichern bzw. das erste mal speichern und das zweite mal updaten (saveOrUpdate). Das ist halt auch nicht die beste Lösung, daher möchte ich es unbedingt mit @PrimaryKeyJoinColumn schaffen, aber das geht irgendwie nicht.



```
final Participant participant = new Participant();
    participant.setFirstname("Sepp");
    participant.setSurname("Maier");
    //participant.setChipnumber("DF-12345");
    final Contact contact = new Contact();
    //contact.setPk_contact(13);
    contact.setEmail("sepp.maier@web.de");
    contact.setTelnumber("0643/3334218697");
    contact.setFax("04353421");
    dao.saveParticipant(participant);
    final int id = participant.getPk_part();
    contact.setPk_contact(id);
    participant.setContact(contact);
    dao.saveParticipant(participant);
```


----------



## Java.getSkill() (8. Mai 2010)

zip mal den ganzen ordner und lad irgendwo hoch


----------



## Generic1 (8. Mai 2010)

Das ist das ganze Projekt:

kostenlos Dateien hochladen bei File Upload X

es handelt sich um ein Netbenas- Projekt, 
Besten Dank,
lg


----------



## Java.getSkill() (8. Mai 2010)

ich hatte noch keine zeit zum Schauen, aber fehlt da nicht bei Contact

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getPk_contact() {
        return pk_contact;
        }


der primary key für jeden neuen contact muss doch in der Table generiert werden?

oder versuch mal

contact.setPk_contact((Integer)1);

contact.setEmail("sepp.maier@web.de");
    contact.setTelnumber("0643/3334218697 begin_of_the_skype_highlighting**************0643/3334218697******end_of_the_skype_highlighting begin_of_the_skype_highlighting              0643/3334218697      end_of_the_skype_highlighting");
    contact.setFax("04353421");
    dao.saveParticipant(participant);


----------



## Generic1 (9. Mai 2010)

```
contact.setPk_contact((Integer)1);
```

naja, genau das will ich ja nicht machen, die Id in der Contact- Tabelle sollte ja genau die gleiche wie in der Participant- Tabelle sein -> also 1:1 und deshalb wollt ich das auch mit:


```
@OneToOne(cascade = CascadeType.ALL)
  @PrimaryKeyJoinColumn
  public Contact getContact() {
    return contact;
    }
```

in der Klasse Participant machen, aber das klappt halt leider nicht, keine Ahung wieso.
Wäre Euch sehr dankbar, wenn ihr euch das nochmal anschauen könntet,
Besten Dank!!!
lg

[EDIT]
Ich hab auch das gefunden, und wollte versuchen, dass umzusetzen aber irgendwie hab ich es nicht hinbekommen, 
One to One Mapping
vielleicht hat jemand von Euch noch einen vorschlag, wie ich das realisieren soll.
Hier noch mal meine SQL- Statements, wie ich die Tabellen erstellt habe:


```
CREATE TABLE TParticipant(pk_part INT NOT NULL AUTO_INCREMENT,
                          firstname   VARCHAR(100) NOT NULL,
                          surname     VARCHAR(150) NOT NULL,
                          chipnumber  VARCHAR(8),
                          PRIMARY KEY(pk_part)
                          ) ENGINE = INNODB;

CREATE TABLE TContact(pk_contact INT NOT NULL,
                      email VARCHAR(80),
                      telnumber VARCHAR(80),
                      fax VARCHAR(80),
                      PRIMARY KEY(pk_contact),
                      FOREIGN KEY(pk_contact) REFERENCES TParticipant(pk_part)
                     ) ENGINE = INNODB;
```


----------



## Java.getSkill() (9. Mai 2010)

Hi, du bist auf dem richtigen Weg, aber das Entscheidende fehlt dir noch 

Wie ich das sehe hast du eine Person und eine Adresse die zusammengehören. Da es auch Personen ohne Adresse geben kann, hängt Adresse von der Person ab. Jetzt möchtest du, dass die ID von der Person auch die ID von Adresse ist. AFAIK generierst du die ID in Person.

@Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  public Integer getPk_part() {
    return pk_part;
    }


In der Adresse musst du neben

@OneToOne(cascade = CascadeType.ALL)
  @PrimaryKeyJoinColumn
  public Contact getContact() {
    return contact;
    }

auch folgendes schreiben 
	
	
	
	





```
@ID
@GeneratedValue(generator="system-foreign") //weil du holst dir ja ID aus Person
@GenericGenerator(name="system-foreign", strategy ="foreign",
parameters =@Parameter(name="property", value="person")) //statt person wohl den participant property schreiben
public Integer getId(){
return id;}
```

Hab das noch nie gemacht

Person person=...
Contact contact=...

person.setContact(contact)

und wenn du es bidirektional machst, also das beide Klassen von der anderen Klasse das Objekt/Property (set/get Person/Contact)

@onetoone(mappedby="propertyDemDieBeziehungGEhört", cascade=Cascadetype.all)
public Person getPerson(){r person;}

contact.setPerson(person)

mit contact.setPeson(null) its wieder weg


----------



## Generic1 (9. Mai 2010)

>> //statt person wohl den participant property schreiben

versteh ich nicht wie du das meinst, ich habe in der Klasse Participant kein property participant!?
Ich hab jetzt keine Ahnung was ich da hinschreiben soll?


```
@Id @GeneratedValue(generator="foreign")
  @GenericGenerator(name="foreign", strategy = "foreign", parameters={
    @Parameter(name="property", value="this")
  })
  @OneToOne(cascade = CascadeType.ALL, optional=false)
  @PrimaryKeyJoinColumn
```

value="this" geht auch nicht, was kann ich da noch machen, kann man das überhaupt auflösen?


----------



## Java.getSkill() (9. Mai 2010)

```
package a1.spring.hibernate.buch;

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

@Entity
@Table(name="person")
public class Person {
	
	public Person(){}
	
	private Integer id;
	private String name;
	//private Adresse adresse;
	
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	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;
	}
		
}
```


```
package a1.spring.hibernate.buch;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
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="adresse")
public class Adresse {
	
	public Adresse(){}
	
	private Integer id;
	private String adresse;
	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="adresse")
	public String getAdresse() {
		return adresse;
	}
	public void setAdresse(String adresse) {
		this.adresse = adresse;
	}
	
	@OneToOne(cascade=CascadeType.ALL)
	@PrimaryKeyJoinColumn
	public Person getPerson() {
		return person;
	}
	public void setPerson(Person person) {
		this.person = person;
	}
	
}
```

Person
id,name
1,Java21
2,jfg
3,Test
4,JScala
5,Last


Adresse
id,adresse
1,Inselasdfasdf
4,newstuff
5,hibernate

bei 2,3 haben die Personen jf,Test keine Adresse, also wurde die ID in Adresse auch automatisch übersprungen

Bei dieser Lösung ist es halt so, dass keine 3. zusätzliche Spalte mit dem unnötigen FK generiert wird. PersonID definiert die dazugehörige AdresseID.

edit: Dieses value gibt anscheinend an, welchem objekt irgendwie zugehört werden soll, wenn PKs generiert werden.


----------



## Generic1 (9. Mai 2010)

Habs jetzt soweit hinbekommen, eine Frage hätte ich noch, wenn ich es so ausführe:


```
final ApplicationContext ctx = new FileSystemXmlApplicationContext("src/service.xml");
    final HibernateAddressDao dao = (HibernateAddressDao) ctx.getBean("addressDao");
    final Person person = new Person();
    person.setPersonname("Niki P");
    final Address address = new Address();
    address.setAddress("Breitlinghausen 1234");
    //address.setPerson(null);
    dao.saveAddress(address);
```

also keine Person zu einer Addresse angeben möchte, bekomme ich folgende Fehlermeldung:


```
attempted to assign id from null one-to-one property: person; nested exception is 
org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: 
person
```

Könntest Du mir deinen Code zeigen, wo du keine Person zu einer Addresse speicherst und wie deine Tabellen aufgebaut sind (SQL)

Besten Dank!!
lg


----------



## Generic1 (9. Mai 2010)

Ich habs geschafft, Besten Dank!!
Das einzige was gefehlt hat ist ein AUTO_INCREMENT im SQL Befehl zum Erstellen der Tabelle TContact,
Hat mir jetzt 3 Tage gekostet aber was solls,
Besten Dank für Eure Hilfe,
lg


----------



## Generic1 (9. Mai 2010)

Vielleicht könntest Du dir den vorletzten Beitrag von mir nochmal ansehen,
Wenn die Person zum Kontakt null sein soll, dass funktioniert noch nicht,
vielleicht wäre möglich, dass du mir dein Beispiel schicktst,
Besten Dank,
lg


----------



## Java.getSkill() (9. Mai 2010)

einen SQL Code habe ich nicht gebraucht.
so sieht z.Bl eine hibernate.cfg.xml bei mir aus:
[XML]<?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.Person" />
<mapping class="a1.spring.hibernate.buch.Adresse" />   

</session-factory>
</hibernate-configuration>[/XML]

<property name="hibernate.hbm2ddl.auto">update</property>
dieses Ding sagt hibernate und mysql, dass es aus den JavaBeans mit Annotation Tabellen in der DB erstellen soll. Du erstellst einfach die Datenbank, bei mir heißt die "filme" und dann macht hibernate automatisch aus dem JavaCode die Tabellen in MySQL


Ich glaube du kannst keine Adressen ohne Person erstellen, da der PK in der Tabelle Adresse/Contact  von der Person/Participant kommt. PrimaryKey von Adresse ist der ForeignKey von Person. Ich konnte bei mir die Tabelle Person auch nicht löschen, da die ganzen PK als FK in Adresse noch drin waren.


----------



## Java.getSkill() (9. Mai 2010)

adresse.setPerson(null); 

wie geahnt, Adresse holt sich PK von Person


```
22:09:17,640 DEBUG SQL:111 - insert into person (name) values (?)
Hibernate: insert into person (name) values (?)
Exception in thread "main" org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: person
	at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:68)
	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:122)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
	at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
	at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
	at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:563)
	at org.hibernate.impl.SessionImpl.save(SessionImpl.java:551)
	at org.hibernate.impl.SessionImpl.save(SessionImpl.java:547)
	at a1.spring.hibernate.buch.App.perad(App.java:103)
	at a1.spring.hibernate.buch.App.main(App.java:40)
```

man kann auch irgendwo bei den ganzen @OneToOne oder ManyToOne Geschichten auch (optional=true) angeben, dann ist es der Tabelle, welche den FK in der neuen Spalte hat, auch erlaubt null Werte als FK zu haben.


```
@OneToOne (optional=true)
@JoinColumn(name="fk_derAnderenTabelle") //das ist jetzt die 3. Spalte die den FK als Referenz enthält
public Xy getXy(){
return xy;}
```


Hast du zur Zeit eine eigene Spalte, die den FK enthält, oder haben alle Tabellen nur die Spalte  mit dem PK?


----------



## Generic1 (10. Mai 2010)

Hallo,

Das hab ich versucht, hat aber nicht geklappt bzw. ist ohne Auswirkung, Ich hab 2 Tabellen in der DB (TParticipant und TContact) welche beide nur Primary keys haben und diese möchte ich verbinden, Ich habe also keine Foreign- key Spalte in TParticipant.



```
@OneToOne(optional=true)
  @PrimaryKeyJoinColumn
  public Contact getContact() {
    return contact;
    }
```

Also wirds da wohl keine Möglichkeit geben, dass ich ohne einer FK Splate auskomme in Addresse/TParticipant schätz ich mal, da der Primary key in Addresse/Participant nicht null sein kann und deshalb auch das obere "optional=true" umsonst ist?
Lieg ich da richtig?


----------



## Generic1 (10. Mai 2010)

Ich hab mir das DB- Schema nochmal angesehen und es sind eh alle 1:1 Beziehungen ein muss, d.h. eine Person muss eh immer eine Addresse auch haben,

Ich hab jetzt versucht eine 1:n Beziehung herzustellen (@ManyToOne) aber da bekomm ich wieder die unterschiedlichsten Fehlermeldungen,
Wäre es möglich dass du das Person-> Adress Beispiel zu einem  ManytoOne Beispiel ummodels, also eine Adresse hat mehrere Personen?
Besten Dank!!
lg


----------



## Java.getSkill() (10. Mai 2010)

> Hallo,
> 
> Das hab ich versucht, hat aber nicht geklappt bzw. ist ohne Auswirkung, Ich hab 2 Tabellen in der DB (TParticipant und TContact) welche beide nur Primary keys haben und diese möchte ich verbinden, Ich habe also keine Foreign- key Spalte in TParticipant.



Die sind schon verbunden, soweit ich das verstehe. Wenn du meine 2 Klassen, die ich gestern gepostet habe, copy paste machst und einfach startest, dann läuft das Ding schon. in der hibernate.cfg.xml siehst du auch dieses "resource class=..". 


```
@OneToOne(optional=true)
  @PrimaryKeyJoinColumn
  public Contact getContact() {
    return contact;
    }
```
hatte ich auch kurz überlegt, aber du kannst ja keine primarykey spalte auf null setzen 
folgendes müsste aber gehen, da hier eine neue Spalte entsteht, die nur FK enthalten soll

@OneToOne (optional=true)
@JoinColumn(name="fk_derAnderenTabelle")

edit: das mit manytoone sollte auch nicht so schwer sein, da muss man wohl mit List <Klasse> liste=new ArrayList<Klasse>(); arbeiten


Benutzt du Eclipse mit Maven?


----------

