Ho due classi Foo
e Bar
. Le tabelle del database simile a questa:Chiave primaria composta, chiave esterna. Riferimento a oggetto o chiave?
|Foo|
|id : INT (PK) | bar_id : INT (PK, FK) |
|Bar|
|id : INT (PK) |
Normalmente avrei mappa in questo modo:
@Entity
public class Bar
{
@Id
@Column(name = "id")
private int id;
@OneToMany
private Set<Foo> foo;
}
@Entity
public class Foo
{
@EmbeddedId
private FooPK key;
@MapsId("barId")
@ManyToOne
@JoinColumn(name = "bar_id", referencedColumnName = "id")
private Bar bar;
}
@Embeddable
public class FooPK
{
@Column(name = "id")
private int id;
@Column(name = "bar_id")
private int barId;
}
Tuttavia i id in FooPK
sono vagamente mappati e devono essere collegati manualmente. Preferirei una soluzione che mappasse usando Oggetti al posto di ID sciolti. Ho provato quanto segue ma (ovviamente) non ha funzionato, ma penso che dà un'idea di quello che vorrei realizzare:
@Entity
public class Bar
{
@Id
@Column(name = "id")
private int id;
@OneToMany
private Set<Foo> foo;
}
@Entity
public class Foo
{
@EmbeddedId
private FooPK key;
@MapsId("barId")
@ManyToOne
@JoinColumn(name = "bar_id", referencedColumnName = "id")
@Access(AccessType.FIELD)
private Bar getBar()
{
return key.getBar();
}
}
@Embeddable
public class FooPK
{
@Column(name = "id")
private int id;
@Transient
private Bar bar;
//....
@Column(name = "bar_id")
@Access(AccessType.PROPERTY)
private int getBarId
{
return bar.getId();
}
}
Un altro problema con quest'ultima soluzione è che il metodo getBarId()
in FooPK
deve avere un metodo setBarId(Int)
. L'impostazione dell'oggetto usando l'ID può essere effettuata accedendo al livello di accesso ai dati, tuttavia questo (a mio avviso) viola la separazione dei livelli business/dominio/dati.
Quindi cosa fare? Vai con la prima soluzione e mantieni gli ID in sincronia manualmente o c'è un'altra (migliore) pratica?
Quindi questo è il primo esempio. Ho visto che questa è "la strada da percorrere", mi stavo chiedendo se il secondo esempio fosse un modo più pulito. Immagino che sia un no allora? – siebz0r
@ siebz0r oh, scusa, non ho notato che il primo esempio era lo stesso; o. Penso che sia più semplice guardare PK quando ci sono ID, non oggetti mappati. Se dovessi cercare in FooPK, avresti bisogno solo di interi e non di oggetti con tutte le proprietà non necessarie. – JMelnik