Ich habe eine Situation, in der ich Tabellen für ein Objekt in einer ORM-Klassenhierarchie verbinden muss, wobei die Join-Spalte NICHT der Primärschlüssel der Basisklasse ist. Hier ist ein Beispiel der Tabelle Design:Wie verknüpfe ich Tabellen in Nicht-Primärschlüsselspalten in Sekundärtabellen?
CREATE TABLE APP.FOO
(
FOO_ID INTEGER NOT NULL,
TYPE_ID INTEGER NOT NULL,
PRIMARY KEY(FOO_ID)
)
CREATE TABLE APP.BAR
(
FOO_ID INTEGER NOT NULL,
BAR_ID INTEGER NOT NULL,
PRIMARY KEY(BAR_ID),
CONSTRAINT bar_fk FOREIGN KEY(FOO_ID) REFERENCES APP.FOO(FOO_ID)
)
CREATE TABLE APP.BAR_NAMES
(
BAR_ID INTEGER NOT NULL,
BAR_NAME VARCHAR(128) NOT NULL,
PRIMARY KEY(BAR_ID, BAR_NAME),
CONSTRAINT bar_names_fk FOREIGN KEY(BAR_ID) REFERENCES APP.BAR(BAR_ID)
)
Und hier sind die Abbildungen (Getter und Setter für Kürze beseitigt
@Entity
@Table(name = "FOO")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TYPE_ID", discriminatorType = javax.persistence.DiscriminatorType.INTEGER)
public abstract class Foo {
@Id
@Column(name = "FOO_ID")
private Long fooId;
}
@Entity
@DiscriminatorValue("1")
@SecondaryTable(name = "BAR", pkJoinColumns = { @PrimaryKeyJoinColumn(name = "FOO_ID", referencedColumnName = "FOO_ID") })
public class Bar extends Foo{
@Column(table = "BAR", name = "BAR_ID")
Long barId;
}
Wie kann ich die Zuordnung für BAR_NAMES
gegeben hinzufügen, dass seine Join-Spalte nicht FOO_ID
, aber BAR_ID
ich folgendes versucht:?
@CollectionOfElements(fetch = FetchType.LAZY)
@Column(name = "BAR_NAME")
@JoinTable(name = "BAR_NAMES", joinColumns = @JoinColumn(table = "BAR", name = "BAR_ID", referencedColumnName="BAR_ID"))
List<String> names = new ArrayList<String>();
Dies schlägt fehl, da das SQL zum Abrufen des Bar-Objekts versucht, einen BAR_ID-Wert aus der FOO-Tabelle abzurufen. Ich habe auch versucht mit
@JoinTable(name = "BAR_NAMES", joinColumns = @JoinColumn(name = "BAR_ID"))
Dies erzeugt keine SQL-Fehler die JoinTable Anmerkung zu ersetzen, sondern ruft auch keine Daten, da die Abfrage gegen BAR_NAMES wird die FOO_ID als Wert beitreten anstelle des BAR_ID.
Zu Testzwecken habe ich
insert into FOO (FOO_ID, TYPE_ID) values (10, 1);
insert into BAR (FOO_ID, BAR_ID) values (10, 20);
insert into BAR_NAMES (BAR_ID, BAR_NAME) values (20, 'HELLO');
Viele Lösungen, die die DB mit den folgenden Befehlen bevölkert, die eine leere Sammlung zu arbeiten erscheint zurück, wenn für ID Foo Objekt bekommen 10 (im Gegensatz zu einer Sammlung enthalten im Gegensatz 1 Name)
'barId' ist immer noch mit' @ Id' markiert, was ist der Unterschied? – deathangel908