Ho una situazione in cui ho bisogno di unire tabelle su un oggetto in una gerarchia di classi ORM in cui la colonna di join NON è la chiave primaria della classe base. Ecco un esempio della struttura della tabella:Come faccio a unire le tabelle su colonne chiave non primarie nelle tabelle secondarie?
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)
)
Ed ecco le mappature (getter e setter eliminati per brevità
@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;
}
Come si aggiunge la mappatura per BAR_NAMES
dato che la sua colonna di join non è FOO_ID
, ma BAR_ID
ho provato quanto segue:?
@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>();
Questo fallisce perché SQL per recuperare l'oggetto barra cerca di ottenere un valore BAR_ID dalla tabella FOO. Ho anche provato a sostituire l'annotazione JoinTable con
@JoinTable(name = "BAR_NAMES", joinColumns = @JoinColumn(name = "BAR_ID"))
Questo produce alcun errore SQL, ma recupera anche dati perché la query BAR_NAMES utilizza il FOO_ID come valore join anziché sul BAR_ID.
A scopo di verifica, ho popolato il DB con i seguenti comandi
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');
Molte soluzioni che sembrano lavorare restituirà un insieme vuoto quando sempre oggetto Foo per ID 10 (al contrario di una raccolta contenente 1 nome)
'barId' è ancora contrassegnato con' @ Id', qual è la differenza? – deathangel908