# Hibernate und Tabellenverknüpfung



## Balian (15. Mai 2008)

Hallo Zusammen,

ich arbeite mich gerade durch ein Hibernatebuch und stelle mir gerade die Frage, wie man folgendes Szenario umsetzt:

1. Tabelle Konten
Kontonummer
Name
Kontoart

2. Tabelle Kontenarten
ID
Kontoart

In der 2. Tabelle sind bereits die Kontoarten vorhanden:
1 Kunde
2 Lieferant

So nun soll ein Kunde gespeichert werden und in der Spalte Kontoart der 1. Tabelle soll als Kontoart die ID der zweiten Tabelle gespeichert werden.-> Kontoart ist also der Fremdschlüssel.

Wie ich das normalerweise mache ist klar, aber bei Hibernate?

Klar, Konten und Kontenarten wird jeweils ein ein Entity aber würde man jetzt irgendwie die Verbindung zwischen den Tabellen definieren? @OneToMany usw scheint mir nicht passend. (Die Kontoarten sind ja auch schon da.)Oder würde man einfach die ID der Kontoart in die "Eigenschaft" Kontoart des Kontenentitys ablegen und dann das Kontenentity persistieren?

Ich hoffe Ihr könnt mich einiger Massen verstehen ;-(

Gruß

    Balian


----------



## Guest (15. Mai 2008)

Doch, das ist ein typischer Fall für ein OneToMany bzw. ManyToOne, je nach dem von welcher Seite man es betrachtet.

```
public class Konto ...
{
   ...

   @ManyToOne(optional=false, ...)
   private Kontoart kontoart;

   ...
}

public class Kontoart ...
{
   ...

   @OneToMany(mappedBy="kontoart", ...)
   private Set<Konto> konten = new HashSet<Konto>();

   ...
}
```


----------



## Gast (15. Mai 2008)

Tatsächlich, dann muss ich mir das nochmal anschauen. Da habe ich bestimmt etwas nicht verstanden. Ich habe das so interpretiert, dass dann auch immer die Kontoart mit angelegt werden würde...


----------



## Balian (19. Mai 2008)

Also ich habe mir die ganze Thematik nochmal angeschaut. Die @OneToMany -Geschicht ist schon das richtige Konstrukt für solche Dinge
allerdings für meine Überlegungen wahrscheinlich nicht wirklich.

Es gibt also ein Konto, welches eine Bezeichnung, eine Nummer, eine Kontoart und Zahlart hat.

Tabellen


Konto -> id, nummer, bezeichnung, kontoart, zahlart
Kontoart -> kurzbezeichnung, bezeichnung
Zahlart -> kurzbezeichnung, bezeichnung

Daten

Kontoart:

GV - Gewinn und Verlustkonten
B  - Bilanzkonten
K - Kunden
L - Lieferanten

Zahlart:

U - Überweisung
S - Scheck

Konten

1 - 10001 - Müller - K - U
2 - 70001 - Meier - L - S

Die beiden Tabellen Kontoart und Zahlart erhalten keine weitere Spalten. Im Prinzip stellen die Kurzbezeichnungen der
Datenbanksätze der Tabellen die möglichen EInträge in der dazugehörigen Spalte der Kontotabelle dar.

Müsste man nun die Tabellen über Fremdschlüssel unbedingt verbinden? Das Konto Entity würde nicht sehr einfach werden. Oder sollte
man von einer statischen Liste ausgehen, das heisst es gibt keine Verbindung über Fremdschlüssel.

Sobald man also die Kontoart in einem Konto hinterlegen möchte, müsste die Anwendung die möglichen Einträge über das Entity Kontoart
ermitteln, wählt die gweünschte kurzbezeichnung und übergibt diese der entsprechenden Kontoentity-variablen.

Wie sollte man sonst Anwendungen realisieren, die soetwas in vielfacher Form haben. Die JPA-Einstellungen würden sehr komplex und kaum realisierbar.

Gruß

    Balian


----------



## byte (19. Mai 2008)

Also für mich sind hier Kontoart und Zahlart überhaupt keine Entitäten mit eigener Tabelle. Es gibt doch nur eine begrenzte (statische) Menge an Ausprägungen davon. Mach doch einfach Enums draus. Die Werte (Ordinalzahl oder String) werden direkt im jeweiligen Konto gespeichert. Auf diese Weise hast Du nur eine Entität Konto und musst nichts joinen.


----------



## Guest (19. Mai 2008)

Ich würde es ungefähr so machen
	
	
	
	





```
Konto
{
   @Id
   private Long id;
   @Column(nullable=false, updateable=false)
   private String nummer;
   @Column(nullable=false)
   private String bezeichnung;

   @ManyToOne(optional=false)
   private Kontoart kontoart;
   @ManyToOne(optional=false)
   private Zahlart zahlart;
}

Kontoart
{
   @Id
   private String kurzbezeichnung;
   @Column(nullable=false)
   private String bezeichnung;

   //optional
   @OneToMany(mappedBy="kontoart")
   private Set<Konto> kontoSet = new HashSet<Konto>();
}

Zahlart
{
   @Id
   private String kurzbezeichnung;
   @Column(nullable=false)
   private String bezeichnung;

   //optional.
   @OneToMany(mappedBy="zahlart")
   private Set<Konto> kontoSet = new HashSet<Konto>();
}
```
Zahlart und Kontoart kannst du clientseitig gut in irgendwelche Comboboxen stecken und stellst damit sicher,
dass nur existierende Einträge verwendet werden können. Aufwändig ist das kaum.
Klar kannst du einfach Strings verwenden, z.B.
	
	
	
	





```
Konto
{
   ...
   @Column(optional=false)
   private String kontoart; // Kurzbezeichnung
   @Column(optional=false)
   private String zahlart; // Kurzbezeichnung
}
```
dann hast du aber clientseitig unnötigen Aufwand bei der Ermittlung der dazugehörigen Einträge aus Zahlart
und Kontoart (bestehender Konto-Datensatz wird in einer Updatemaske geladen, ComboBox mit Kontoarten 
soll auf den korrekten Eintrag positioniert werden usw.)

Andere Sache ist wieder die Auswahl von Einträgen eines bestimmten Typs. z.B. Alle Konten der Kontoart 'Kunden'.
Andere Darstellung in der Suchmaske (komplette Bezeichnung), zum Server geht aber ein normaler String.

@byto
Wie gehtst du auch vor, wenn du neue Kontoarten oder Zahlarten hinzufügen willst? Irgendwelche Enums editieren 
und die Anwendung neu übersetzen, deployen etc.? Die paar Join operationen kosten so gut wie keine Zeit.


----------



## Balian (21. Mai 2008)

Danke erstmal für die Antworten. Ganz sicher bin ich mir immer noch nicht. Da allerdings die Tabellen Kontoart und Zahlart wirklich nur die Bezeichnungen der Abkürzung enthalten, sollte die Entitäten nicht mit der Kontoentität per Fremdschlüssel verknüpft werden. Die Tabellen dienen ja nur zum "aufbewahren" der Bezeichungen, sind nicht im Quellcode.

Gruß

    Balian


----------

