我有两个班级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;
}
但是,id 的FooPK
映射很松散,需要手动连接。我更喜欢使用对象而不是松散 id 进行映射的解决方案。我尝试了以下方法,但(当然)它没有用,但我认为它可以让我了解我想要实现的目标:
@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)
方法。可以通过访问数据访问层来使用 ID 设置对象,但是(在我看来)这违反了业务/域/数据层的分离。
那么该怎么办?使用第一个解决方案并手动保持 id 同步,还是有另一种(最佳)做法?