Mam dwie klasy Foo
i Bar
. Tabele w bazie wyglądać następująco:Złożony klucz podstawowy, klucz obcy. Odniesienie do obiektu lub klucza?
|Foo|
|id : INT (PK) | bar_id : INT (PK, FK) |
|Bar|
|id : INT (PK) |
Normalnie bym map to tak:
@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;
}
Jednak id w FooPK
odwzorowywane są luźno i muszą być połączone ręcznie. Wolałbym rozwiązanie, które mapuje używając obiektów zamiast luźnych identyfikatorów. Próbowałem następujących ale (oczywiście) to nie działa, ale myślę, że to daje wyobrażenie o tym, co chciałbym osiągnąć:
@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();
}
}
Kolejny problem z tym ostatnim rozwiązania jest to, że sposób w getBarId()
FooPK
musi mieć metodę setBarId(Int)
. Ustawienie obiektu przy użyciu identyfikatora można wykonać, uzyskując dostęp do warstwy dostępu do danych, jednak to (moim zdaniem) narusza separację warstw biznesowych/domenowych/danych.
Co robić? Idź z pierwszym rozwiązaniem i synchronizuj identyfikatory ręcznie lub czy istnieje kolejna (najlepsza) praktyka?
To pierwszy przykład. Widziałem, że jest to "droga do wyjścia", zastanawiałem się tylko, czy drugi przykład był czystszy. Chyba to nie jest? – siebz0r
@ siebz0r oh, przepraszam, nie zauważyłem, pierwszy przykład był taki sam; Myślę, że łatwiej jest spojrzeć na PK, gdy są identyfikatory, a nie odwzorowane obiekty. Jeśli chcesz przeszukiwać FooPK, potrzebujesz tylko liczb całkowitych, a nie obiektów ze wszystkimi niepotrzebnymi właściwościami. – JMelnik