【问题标题】:Controlling what is lazy (or eager) loaded控制什么是惰性(或急切)加载的
【发布时间】:2014-04-01 06:59:16
【问题描述】:

我目前的结构如下(伪代码):

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 仅在 orderline 端检查外键,是否有办法在延迟(或急切)加载时为客户端添加检查?

我想在不使用 Hibernate 或 Eclipselink 等特定实现的情况下解决此问题,以便在必要时轻松切换实现。

【问题讨论】:

  • 你要做什么检查..?
  • 我想检查一下客户端属性,所以我可以获取属于订单 123 和客户端 X 的订单。
  • 您是说您需要根据订单 ID 和客户 ID 获取值..!!我说的对吗??
  • 理想情况下你不在乎。当您访问 orderLines 列表时,JPA 将获取它(如果尚未获取)。
  • 查看我的类似问题,它包含代码片段:stackoverflow.com/q/21647947/1639556

标签: java jpa-2.0


【解决方案1】:

如果您只是使用“ID (123)”作为订单实体的 ID,那么您选择的 ID 可能还不够。

在 JPA 中,每个实体都应该有一个唯一的标识符。如果有两个订单(一个用于 X,一个用于 Y)使用相同的 ID,那么一切都会搞砸。

我个人的建议是让 ID 在整个系统中都是唯一的。如果您想要每个客户端的某种序列号,请将其保留为另一个字段。

当然,还有另一种选择,将 Client ID 和 Order 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;
}

【讨论】:

  • 我还没有考虑过某种序列,这听起来像是一个可行的解决方案。谢谢!
猜你喜欢
  • 2010-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-19
相关资源
最近更新 更多