У меня есть два класса Foo
и Bar
. Таблицы в базе данных выглядят следующим образом:
|Foo|
|id : INT (PK) | bar_id : INT (PK, FK) |
|Bar|
|id : INT (PK) |
Обычно я бы сопоставил это так:
@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;
}
Однако идентификаторы в FooPK
слабо сопоставлены, и их нужно подключать вручную. Я бы предпочел решение, которое отображает с использованием объектов вместо свободных идентификаторов.Я попробовал следующее, но (конечно) это не сработало, но я думаю, что это дает представление о том, чего я хотел бы достичь:
@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();
}
}
Другая проблема с последним решением заключается в том, что getBarId()
в FooPK
должен иметь метод setBarId(Int)
. Установка объекта с использованием идентификатора может быть выполнена путем доступа к уровню доступа к данным, однако это (на мой взгляд) нарушает разделение уровней бизнеса/домена/данных.
Так что же делать? Воспользуйтесь первым решением и синхронизируйте идентификаторы вручную или есть другая (лучшая) практика?