【问题标题】:Understanding the Lazy fetch了解延迟获取
【发布时间】:2026-02-02 17:15:01
【问题描述】:
@Entity
public class Bid {

    @Id
    @GeneratedValue
    @Column(name = "bid_id")
    private Long bidId;

    @Column(name = "bid_amt")
    private double bidAmount;

    @Basic(fetch = FetchType.LAZY, optional = false)
    private String person;

    @ManyToOne(targetEntity = Item.class, fetch = FetchType.LAZY)
    @JoinColumn(name = "bid_item", referencedColumnName = "item_id", nullable = false)
    private Item item;

    public Long getBidId() {
        return bidId;
    }

    public double getBidAmount() {
        return bidAmount;
    }

    public String getPerson() {
        return person;
    }

    public Item getItem() {
        return item;
    }

    public void setBidAmount(final double bidAmount) {
        this.bidAmount = bidAmount;
    }

    public void setPerson(final String person) {
        this.person = person;
    }

    public void setItem(final Item item) {
        this.item = item;
    }

    public Bid() {
    }

    @Override
    public String toString() {
        return "Bid [bidId=" + bidId + ", bidAmount=" + bidAmount + ", person="
                + person + /* ", item=" + item + */"]";
    }

}

测试用例:

@Test
    public void testBidRead() {
        final Session currentSession = sessionFactory.getCurrentSession();
        final List<Bid> bids = currentSession.createQuery("from Bid").list();
        for (final Bid bid : bids) {
            System.out.println(bid);
        }
    }

Hibernate 生成的 SQL 是:

/* 
from
    Bid */ select
        bid0_.bid_id as bid1_1_,
        bid0_.bid_amt as bid2_1_,
        bid0_.bid_item as bid4_1_,
        bid0_.person as person1_ 
    from
        Bid bid0_

问题:虽然我将person 属性标记为lazy && optional,但为什么它是SQL 查询的一部分?这是否意味着 Hibernate 不会延迟获取?项目也是如此。

如何延迟获取属性?

【问题讨论】:

    标签: java hibernate lazy-loading


    【解决方案1】:

    要使 person 属性(相对于关联)真正变得懒惰,您必须在构建时对您的类进行字节码检测。参考文档有一些关于如何做的信息。

    http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#performance-fetching-lazyproperties

    【讨论】:

      【解决方案2】:

      Person 是单个(字符串)属性

      在同一个对象上进行其他提取(对于像 bidIdbidAmount 这样的非惰性提取)时获取它是常识

      由于无论如何都必须执行查询,因此传输varchar(或其他)以及bidIdbidAmount 的开销并不大

      它加载到项目 id 中(不是项目本身),以便在您调用 getItem() 时可以加载项目本身,而无需其他查询来获取 id(在两者之间缓存 id构造和getItem()调用)

      【讨论】:

        【解决方案3】:

        hibernate 似乎只加载外键值,而不是整个 Person 或 Item。它有什么问题?

        【讨论】: