我目前的结构如下(伪代码):
public class Order
{
@OneToMany(targetEntity = Orderline.class, fetch = FetchType.LAZY)
private List<Orderline> orderlines;
private Client client;
}
public class Orderline
{
@ManyToOne(mappedBy = 'orderlines')
private Order order;
private Client client;
}
public class Client
{
// your usual Client class, its contents aren't important for the question
}
假设我可以拥有ID为123的订单,该订单属于客户端X.我也可以拥有ID为123的订单,该订单属于客户端Y.当延迟加载(或急切加载,就此而言)时,怎么能我知道当我从数据库中获取客户端X的ID为123的订单时,我不能从客户端Y获取订单线?如果JPA仅检查订单行侧的外键,是否有办法在延迟(或急切)加载时为客户端添加检查?
我想在不使用Hibernate或Eclipselink这样的特定实现的情况下解决这个问题,这样我就可以在必要时轻松切换实现。
答案 0 :(得分:2)
如果您只是使用&#34; ID(123)&#34;您选择的ID可能是不够的。作为订单实体的ID。
在JPA中,每个实体都应具有唯一标识符。如果有两个订单(一个用于X,一个用于Y)使用相同的ID,那么一切都搞砸了。
我个人的建议是在整个系统中使ID唯一。如果您希望每个客户端使用某种序列号,请将其保留为另一个字段。
当然,还有另一种选择,即将客户ID和订单ID作为复合键。
简而言之,请确保您选择的ID可以唯一地标识实体(通常表示DB中的一行)。
示例(第一种方法,唯一ID)
public class Order
{
@Id
private Long id;
@OneToMany(targetEntity = Orderline.class, fetch = FetchType.LAZY)
private List<Orderline> orderlines;
private Client client;
private Long orderSequence; // unique within a client
}
public class Orderline
{
@Id
private Long id; // unique ID of order line
@ManyToOne(mappedBy = 'orderlines')
private Order order;
// not necessary, as you can access through orderLine.order.client
// private Client client;
}
第二种方法(复合键):
public class Order
{
@EmbeddedId
private OrderId id;
@ManyToOne
@JoinColumn(insertable=false, updatable=false)
private Client client;
@Column(insertable=false, updatable=false)
private Long orderSequence; // unique within a client
@OneToMany(targetEntity = Orderline.class, fetch = FetchType.LAZY)
private List<Orderline> orderlines;
}
@Embeddable
public class OrderId {
Long clientId;
Long orderSequence;
}