java - Hibernate - FetchType.LAZY 急切地加载数据

标签 java hibernate jpa orm fetch

Hibernate 新手尝试理解 LAZY 和 EAGER 抓取之间的差异。

地址模型:

@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()); 
        }
    }

当我从数据库加载部门对象时,将执行以下查询。

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

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

最佳答案

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

The LAZY strategy is a hint to the persistence provider runtime that data should be fetched lazily when it is first accessed. The implementation is permitted to eagerly fetch data for which the LAZY strategy hint has been specified.

对于 OneToOne 可选依赖项(如您的情况)尤其如此。

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

关于java - Hibernate - FetchType.LAZY 急切地加载数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42996348/

相关文章:

java - Android Parcelable 无法实例化类型

java - Android 中的平面图实现

java - 序列化 hibernate 模型及其延迟加载对象

java - 分离的实体传递到持久化 : JPA inheritance

sql - 用于加入子查询的 JPA CriteriaBuilder

java - 切换cardLayout后JPanel不会关闭

java - 调度程序可以挂起一个线程并执行另一个线程/工作吗?

java - Spring @Transactional 方法不回滚

java - JPA Hibernate OneToMany 枚举 - 未映射的类错误

java - 在 CRUD 问题中添加功能时出现问题