【问题标题】:Hibernate - FetchType.LAZY loads data eagerlyHibernate - FetchType.LAZY 急切地加载数据
【发布时间】:2017-03-24 09:56:37
【问题描述】:

Hibernate newb 试图理解 LAZY 和 EAGER fetching 之间的区别。

地址模型:

@Entity
public class Address {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column
    private String street;

    @Column
    private String city;

    @OneToOne
    private Department department;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    @Override
    public String toString() {
        return "Address [id=" + id + ", street=" + street + ", city=" + city + "]";
    }
}

部门型号:

@Entity
public class Department {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column
    private String name;

    @OneToOne(mappedBy = "department", fetch = FetchType.LAZY)
    private Address address;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Department [id=" + id + ", name=" + name + "]";
    }
}

测试方法:

@Test
    public void testDepartment() {
        Long departmentID;
        Department department;

        Long addressId;
        Address address;

        try (Session session = SessionUtil.getSession()) {
            Transaction tx = session.beginTransaction();

            department = new Department();
            department.setId(69L);
            department.setName("company");

            address = new Address();
            address.setCity("city");
            address.setStreet("street");
            address.setDepartment(department);

            session.save(department);
            session.save(address);

            departmentID = department.getId();
            addressId = address.getId();
            tx.commit();
        }

        try (Session session = SessionUtil.getSession()) {          
            department = session.load(Department.class, departmentID);
            System.out.println(department.getId()); 
        }
    }

当我从 db 加载部门对象时,会执行以下查询。

Hibernate: select department0_.id as id1_2_0_, department0_.name as name2_2_0_ from Department department0_ where department0_.id=?
Hibernate: select address0_.id as id1_0_1_, address0_.city as city2_0_1_, address0_.department_id as departme4_0_1_, address0_.street as street3_0_1_, department1_.id as id1_2_0_, department1_.name as name2_2_0_ from Address address0_ left outer join Department department1_ on address0_.department_id=department1_.id where address0_.department_id=?
1

看到连接选择查询我很惊讶,因为我从不明确要求地址对象,它应该被延迟加载。

【问题讨论】:

    标签: java hibernate jpa orm fetch


    【解决方案1】:

    如果您查看 FetchType.LAZY 的 javadoc,您会发现没有任何保证(与 EAGER fetchinig 不同):

    LAZY 策略是对持久性提供程序运行时的提示, 首次访问数据时应延迟获取数据。这 允许实现急切地获取 LAZY 的数据 已指定策略提示。

    这对于 OneToOne 可选依赖项尤其如此。

    如果你真的需要为这种关系实现延迟加载,这里有一些解决方法的进一步阅读:post 1post 2

    【讨论】:

      猜你喜欢
      • 2013-07-28
      • 2017-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多