# @JoinColumns



## shadow (12. Mrz 2008)

Hallo,

ich habe ein Problem mit JPA, genauer: Die Annotation @JoinColumns ....

Es geht darum, dass ich eine Java-GUI zu einer bestehenden Datenbank entwickle. Diese DB soll im Idealfall nicht verändert werden.
Bei meinem Problem geht es um zwei Tabellen: TABELLE1 und TABELLE2. Beide haben ein Feld ID, das der Primärschlüssel ist.

Nun möchte ich eine Verbindung zwischen diesen beiden Tabellen herstellen, jedoch nicht über den Primärschlüssel, sondern über zwei andere Felder, die es in beiden Tabellen gibt: FELD_A und FELD_B ...

Also schreibe ich in Tabelle1.java:


```
@OneToOne
    @JoinColumns({
        @JoinColumn(name="FELD_A", referencedColumnName="FELD_A"),
        @JoinColumn(name="FELD_B", referencedColumnName="FELD_B")
    })    
    private Tabelle2 tabelle2;
```

Das Programm wirft jedoch beim Start folgende Exception



> Exception Description: A @JoinColumns was specified on the annotated element [private Tabelle2 tabelle2] from the entity class [Tabelle1]. When the source entity class uses a single primary key, only a single (or zero) @JoinColumn should be specified.



Wie gehe ich mit dieser Fehlermeldung um?
Zuerst dachte ich, dass der "referencedColumnName" immer ein Primärschlüssel-Feld von TABELLE2 sein muss. Dem ist aber nicht so. An einer anderen Stelle in meinem Programm habe ich auch schon eine @OneToOne-Verknüpfung gemacht, da ist das "referencedColumName"-Feld auch kein Primärschlüssel-Feld. Warum geht es also hier nicht?

Als Test habe ich den Primärschlüssel in TABELLE2 vom Feld ID auf die Felder FELD_A und FELD_B umgestellt und dies auch in meiner Entity-Class Tabelle2 umgestellt. Dann funktioniert die Verknüpfung. Allerdings ist doch ID eigentlich mein Primärschlüssel und diese Umstellung hat an anderen Stellen in meinem Programm wieder Konsequenzen....

Danke für die Hilfe!

Stefan.


----------



## benders (13. Mrz 2008)

Hi Stefan,

ich lese die Fehlermeldung so:

In der Tabelle2_EntityClass ist der PK auf die Id gesetzt.

Um @JoinColumns zu nutzen, müsste in Tabelle2_EntityClass ein
"composite primary key" definiert sein.


Bernd


----------



## shadow (13. Mrz 2008)

benders hat gesagt.:
			
		

> In der Tabelle2_EntityClass ist der PK auf die Id gesetzt.
> 
> Um @JoinColumns zu nutzen, müsste in Tabelle2_EntityClass ein
> "composite primary key" definiert sein.



Danke für die Antwort!

Richtig, in TABELLE2 müssten (!) genau die zwei Felder Primärschlüssel sein, über die ich die Verbindung herstellen will...
Tatsache ist aber, dass der Primärschlüssel auf der ID liegt. Kann ich die Verbindung trotzdem irgendwie herstellen?
Ich hatte es schon gehofft, weil, wie bereits oben angeschnitten, kann ich die Annotation @JoinColumn (Achtung, hier Singular) mit einem Feld beispielsweise aus TABELLE3 verknüpfen, das kein Primärschlüssel ist.


----------



## benders (19. Mrz 2008)

Sorry für die späte Antwort, aber ich hatte keine EMail erhalten.

Für die Tabelle1 und Tabelle2 hast Du jeweils eine EntityClass.

Innerhalb der Entity1 definierst Du ein @Transient Feld vom Typ Entity2.
In der get-Methode holst Du Dir den passende Eintrag aus der Tabelle2.
z.B über eine LocalSessionBean.

Bernd


----------



## shadow (20. Mrz 2008)

Das mit dem Transient Field ist eine gute Idee.

Leider bin ich nicht wirklich firm mit EJB, da es bei mir um eine Swing-Anwendung geht. Deswegen kann ich mit LocalSessionBean auch noch nichts anfangen... Da muss ich mich wohl erst noch einlesen. Aber ich habe zumindest die Idee verstanden. Quasi das zugehörige Objekt einfach manuell laden.

Vielen Dank für die Hilfe!!

Schönen Gruß,
Stefan.


----------



## benders (25. Mrz 2008)

Hi Stefan,

ja die Idee hast Du richtig verstanden.

Deployst Du die Anwendung, denn nicht auf einen Application-Server? (glassfish, jboss,...)

Wenn Du das tust, brauchst Du auf jeden Fall Session-Bean.

LocalSBs sind schneller, können aber nur innerhalb des App-Servers genutzt werden. Z.B. bei der Kommunikation der Entities untereinander. 

RemoteSB haben einen höheren Overhead, und sind deshalb langsamer. Sie können aber auch von einer Swing-Anwendung, der auf den Client läuft benutzt werden.

Typisch für SBs ist zB. das CRUD-Pattern.


Bernd


----------



## SnooP (25. Mrz 2008)

Im Normalfalls sollte das aber über die JoinColumns gehen... wie der Name schon sagt, sind das ja die Spalten, über die gejoined werden kann und das kann man ja wohl in der Regel auch bei Nicht-PKs  ...

ich vermute die one-to-one hinter dem Problem... probier mal ne one-to-many mit unique=true.


----------



## shadow (30. Apr 2008)

Hallo,

es hat zwar sehr lange gedauert, aber jetzt konnte ich es endlich einmal ausprobieren.

Also mit @OneToMany kann ich hier nicht arbeiten, weil diese Annotation eine Collection erwartet, ich hab hier aber ein normales Objekt (Tabelle2)...

Mir bleibt also (soweit ich das sehe) nur die Möglichkeit, die benötigten Objekte von Hand zu laden... Schade!


----------

