JPA 选择,啥应该延迟加载,当不需要时

Posted

技术标签:

【中文标题】JPA 选择,啥应该延迟加载,当不需要时【英文标题】:JPA selecting, what should be lazy loaded, when not necessaryJPA 选择,什么应该延迟加载,当不需要时 【发布时间】:2013-08-09 15:26:22 【问题描述】:

我有一个映射到这个类的表:

@Entity(name = "status_history")
    @Table
    public class StatusChange implements Comparable<StatusChange> 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @Column(name = "when_")
    @Temporal(TemporalType.TIMESTAMP)
    private Date when;
    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "ordering_id")
    private Ordering ordering;
    private Short status;
    ...



@Override
public int hashCode() 
    return id.intValue();


@Override
public boolean equals(Object o) 
    if (o instanceof StatusChange) 
        StatusChange sc = (StatusChange) o;
        if (id == null) 
            return false;
        
        return id.equals(sc.getId());
    
    return false;

    ...

它有 5006 行。为什么记录显示,当我执行此查询时:

 Query query = em.createQuery("SELECT DISTINCT sh FROM status_history sh");
 return query.getResultList();

日志显示 JPA 也在获取相关类:

[EL Fine]: sql: 2013-08-09 17:02:52.631--ServerSession(27039955)--Connection(12972016)--Thread(Thread[main,5,main])--SELECT ID, TYPE, anniversary_newspapers, anniversary_newspapers_type, AUTHOR, copy_color, copy_format, decorated_folder, decorated_folder_note, delivery_type, publishing_description, SIGNATURE, TITLE, USAGE, work_amount, work_amount_desc, work_type, year_, BARCODE, comment_, denial_reason, EXHIBITION, exhibition_name, further_processing, LZA, no_new_scans, ONLINE, RESTORATION, SMALL, URGENT FROM ordered_object WHERE (ID = ?)
    bind => [54]
[EL Fine]: sql: 2013-08-09 17:02:52.632--ServerSession(27039955)--Connection(12972016)--Thread(Thread[main,5,main])--SELECT ID, TYPE, cancel_comment, claim_comment, COMMUNICATION, EDITOR, internal_id, LOCATION, STATUS, YEAR, yearly_number, billing_contact_id, oo_id, orderer_id, accumulated, customer_created, estimated_price, no_barcode, no_object, accumulated_id FROM ORDERING WHERE (oo_id = ?)
    bind => [54]
[EL Fine]: sql: 2013-08-09 17:02:52.634--ServerSession(27039955)--Connection(12972016)--Thread(Thread[main,5,main])--SELECT ID, _comment, control_finished, CONTROLLER, date_of_entry, empty_pages, scan_finished, scan_method1, scan_method2, scan_operator, SCANNER, SENDER, thumbnail_number, total_pages, oo_id FROM SCAN_INFO WHERE (oo_id = ?)
    bind => [54]
[EL Fine]: sql: 2013-08-09 17:02:52.635--ServerSession(27039955)--Connection(12972016)--Thread(Thread[main,5,main])--SELECT ID, onb_employee, contact_id FROM ORDERER WHERE (ID = ?)
    bind => [54]

查询需要 30 秒。我在这里想念什么? 提前非常感谢!

【问题讨论】:

【参考方案1】:

EclipseLink 需要启用编织以允许在 OneToOne 和 ManyToOne 关系上使用惰性,否则只是一个提示 文档 http://www.eclipse.org/eclipselink/documentation/2.4/concepts/app_dev007.htm 包含有关使用 EclipseLink 进行编织的信息以及有关在不使用时如何设置它的链接。 这在 JPA 兼容的应用服务器中是自动的,因此通常在演示和教程中被忽略。

您还可以使用加入或批量读取来加速关联的参考查找,但对于编织和惰性关系可能不是必需的。 http://wiki.eclipse.org/EclipseLink/Examples/JPA/QueryOptimization

【讨论】:

是的,我同时想到了。抱歉,打扰并感谢您的回复!

以上是关于JPA 选择,啥应该延迟加载,当不需要时的主要内容,如果未能解决你的问题,请参考以下文章

Jpa/Hibernate 字节码增强:字段延迟加载

延迟加载有效,但不应该

JPA:哪些实现支持延迟加载外部事务?

使用 FetchType.LAZY 防止 JPA/Hibernate 中的延迟加载(尤其是在使用 @Transactional 时)?

延迟加载 Spring Data JPA 存储库

JPA 延迟加载