sie*_*z0r 14 java jpa composite-key
我有两个类Foo和Bar.数据库中的表格如下所示:
|Foo|
|id : INT (PK) | bar_id : INT (PK, FK) |
|Bar|
|id : INT (PK) |
Run Code Online (Sandbox Code Playgroud)
通常我会像这样映射它:
@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;
}
Run Code Online (Sandbox Code Playgroud)
但是,id的内容FooPK是松散映射的,需要手动连接.我更喜欢使用Objects映射而不是松散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();
}
}
Run Code Online (Sandbox Code Playgroud)
后一解决方案的另一个问题是该getBarId()方法FooPK需要具有setBarId(Int)方法.使用ID设置对象可以通过访问数据访问层来完成,但是(在我看来)这违反了业务/域/数据层的分离.
那么该怎么办?使用第一个解决方案并手动保持ID同步或是否有其他(最佳)练习?
JMe*_*nik 23
参考JPA 2:复合主键类讨论,对Foo和FooPK类进行以下更改:
@Entity
public class Foo {
@EmbeddedId
private FooPK key;
@MapsId("barId") //references EmbeddedId's property
@JoinColumn(name = "bar_id", referencedColumnName = "id")
@ManyToOne
private Bar bar;
}
@Embeddable
public class FooPK {
@Column(name = "id")
private int id;
@Column(name = "bar_id")
private int barId;
}
Run Code Online (Sandbox Code Playgroud)
我建议首先使用FIELD访问,然后应用PROPERTY访问.
那么该怎么办?使用第一个解决方案并手动保持ID同步或是否有其他(最佳)练习?
避免痛苦 - 自动生成ID.