简体   繁体   English

控制什么是懒惰(或急切)加载

[英]Controlling what is lazy (or eager) loaded

I currently have a structure as follows (pseudocode): 我目前有一个如下结构(伪代码):

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
}

Say that I can have an order with ID 123, which belongs to client X. I can also have an order with ID 123 which belongs to client Y. When lazy loading (or eager loading, for that matter), how can I know that when I fetch order with ID 123 for client X from the database, I won't be getting the orderlines from client Y? 假设我可以拥有ID为123的订单,该订单属于客户端X.我也可以拥有ID为123的订单,该订单属于客户端Y.当延迟加载(或急切加载,就此而言)时,我怎么知道当我从数据库中获取客户端X的ID为123的订单时,我不会从客户端Y获取订单行? If JPA checks on the foreign key on the orderline side only, is there a way to add a check for the client when lazy (or eager) loading? 如果JPA仅检查订单行侧的外键,是否有办法在延迟(或急切)加载时为客户端添加检查?

I would like to solve this without using specific implementations like Hibernate or Eclipselink so I can easily switch between implementations if necessary. 我想在不使用Hibernate或Eclipselink等特定实现的情况下解决这个问题,这样我就可以在必要时轻松切换实现。

Your choice of ID is probably not sufficient if you are just using the "ID (123)" as the ID of the Order entity. 如果您只是使用“ID(123)”作为Order实体的ID,则您对ID的选择可能不够。

In JPA, each entity should have a unique identifier. 在JPA中,每个实体都应具有唯一标识符。 If there are going to be two Orders (one for X and one for Y) using the same ID, then everything is messed up. 如果有两个订单(一个用于X,一个用于Y)使用相同的ID,那么一切都搞砸了。

My personal recommendation is to make ID unique across the whole system. 我个人的建议是在整个系统中使ID唯一。 If you want some kind of sequence number per client, keep it as another field. 如果您希望每个客户端使用某种序列号,请将其保留为另一个字段。

Of course, there is another choice of making Client ID and Order ID as a composite key. 当然,还有另一种选择,即将客户ID和订单ID作为复合密钥。

In short, make sure your choice of ID can uniquely identify an entity (usually means, a row in DB). 简而言之,确保您选择的ID可以唯一地标识实体(通常表示DB中的行)。

An example (First approach, unique ID) 一个例子(第一种方法,唯一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;
}

Second approach (Composite key): 第二种方法(复合键):

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM