Tengo dos clases Foo
y Bar
. En las tablas de la base de datos se ven así:Clave primaria compuesta, clave externa. ¿Referencia a objeto o clave?
|Foo|
|id : INT (PK) | bar_id : INT (PK, FK) |
|Bar|
|id : INT (PK) |
Normalmente habría mapa de esta manera:
@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;
}
Sin embargo, los identificadores de FooPK
se asignan libremente y necesitan ser conectados manualmente. Preferiría una solución que haga mapas utilizando objetos en lugar de identificadores sueltos. He intentado lo siguiente, pero (por supuesto) no funcionó, pero creo que da una idea de lo que me gustaría lograr:
@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();
}
}
Otro problema con esta última solución es que el método de getBarId()
FooPK
necesita tener un método setBarId(Int)
. Establecer el Objeto usando la ID se puede hacer accediendo a la capa de acceso a los datos, sin embargo esto (en mi opinión) viola la separación de las capas de negocios/dominio/datos.
¿Qué hacer? Vaya con la primera solución y mantenga los identificadores sincronizados manualmente o ¿hay alguna otra (mejor) práctica?
Así que ese es el primer ejemplo. He visto que este es 'el camino a seguir', me preguntaba si el segundo ejemplo era una manera más limpia. Supongo que es un no, ¿entonces? – siebz0r
@ siebz0r oh, lo siento, no me di cuenta de que el primer ejemplo era el mismo; o. Creo que es más fácil ver PK cuando hay IDs, no objetos asignados. Si buscara por FooPK, necesitaría solo enteros y no Objetos con todas las propiedades innecesarias. – JMelnik