JPA fetchType.Lazy无法正常工作 [英] JPA fetchType.Lazy is not working

查看:226
本文介绍了JPA fetchType.Lazy无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试fetchType.Lazy的示例,但是在调试代码时,似乎fetchType.Lazy无法正常工作.

I am trying examples for fetchType.Lazy, however while debugging the code, it seems that fetchType.Lazy is not working.

实体bean:地址

在区域字段中添加了具有属性fetch = fetchType.Lazy的注释@Basic.

Added annotation @Basic with property fetch=fetchType.Lazy on district field.

我的实体bean由以下代码定义:

My entity bean is defined by the code below:

    package model;

    import java.io.Serializable;
    import javax.persistence.*;
    import java.util.List;


    /**
     * The persistent class for the address database table.
     */
    @Entity
    @Table(name="address", schema="home")
    public class Address implements Serializable {
        private static final long serialVersionUID = 1L;

        @TableGenerator(name = "addr_gen", table = "table_generator", pkColumnName = "gen_name", valueColumnName = "gen_val", allocationSize=1)
        @Id
        @GeneratedValue(strategy=GenerationType.TABLE, generator="addr_gen")
        private String addressId;

        private String city;

        @Basic(fetch=FetchType.LAZY)
        @Column(name="district")
        private String district;

        private String houseNumber;

        private String pincode;

        private String state;

        private String street;

        //bi-directional many-to-one association to Employee
        @OneToMany(mappedBy="address")
        private List<Employee> employees;

        public Address() {
        }


        public String getAddressId() {
            return this.addressId;
        }

        public void setAddressId(String addressId) {
            this.addressId = addressId;
        }

        public String getCity() {
            return this.city;
        }

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

        public String getDistrict() {
            return this.district;
        }

        public void setDistrict(String district) {
            this.district = district;
        }

        public String getHouseNumber() {
            return this.houseNumber;
        }

        public void setHouseNumber(String houseNumber) {
            this.houseNumber = houseNumber;
        }

        public String getPincode() {
            return this.pincode;
        }

        public void setPincode(String pincode) {
            this.pincode = pincode;
        }

        public String getState() {
            return this.state;
        }

        public void setState(String state) {
            this.state = state;
        }

        public String getStreet() {
            return this.street;
        }

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

        public List<Employee> getEmployees() {
            return this.employees;
        }

        public void setEmployees(List<Employee> employees) {
            this.employees = employees;
        }


        public Employee addEmployees(Employee employees) {
            getEmployees().add(employees);
            employees.setAddress(this);

            return employees;
        }

        public Employee removeEmployees(Employee employees) {
            getEmployees().remove(employees);
            employees.setAddress(null);

            return employees;
        }

        /*@Override
        public String toString() {
            return "Address [addressId=" + addressId + ", city=" + city
                    + ", district=" + district + ", houseNumber=" + houseNumber
                    + ", pincode=" + pincode + ", state=" + state + ", street="
                    + street + ", employees=" + employees + "]";
        }*/
    }

使用上述实体bean的方法:

The method which uses above entity bean:

public Address findAddress(EntityManagerFactory emf, UserTransaction tx) {
    EntityManager em = emf.createEntityManager();
    Address addr = null;
    try {
        tx.begin();
        addr = em.find(Address.class, new String("154"));
        tx.commit();
    } catch (Exception e) {
        e.printStackTrace();
    }

    return addr;
}

因此,在find方法调用之后,当我检查地址对象时,已经在分区中填充了地址.

So after the find method call, when I inspected the address object, it was already populated with district field.

请让我知道我是否缺少某些配置,或者代码本身是否存在问题.

Please let me know whether I am missing some configuration or whether there is some issue with the code itself.

推荐答案

问题在于,在@Basic批注中使用时,应用服务器可以/可以自行决定何时获取数据.如此处

The problem is that when using in the @Basic annotation the application server can/may decide on his own, when it is better to fetch the data. As documented here

EAGER 策略是持久性提供程序运行时的要求,必须热切地获取该值. LAZY 策略是持久性提供程序运行时的提示.

The EAGER strategy is a requirement on the persistence provider runtime that the value must be eagerly fetched. The LAZY strategy is a hint to the persistence provider runtime.

类似于

@OneToMany的注释根据文档相同的问题,但是在那种情况下,JPA提供者将更有可能考虑FetchType提示.

@OneToMany-like annotations have according to the documentation the same problem, but in that case it much more likely that the JPA provider will consider the FetchType hint.

另一方面,您可以尝试使用大数据字段,例如

On the other hand, you could try with a big data field, like

@Lob
@Basic(fetch=FetchType.LAZY)
private byte[] document;

查看是否有更改(尽管再次,您的应用服务器可以决定总是获取该字段).

to see whether something changes (although again, your application server can decide to fetch always the field).

为了检查是否已加载收集字段,我将检查数据库查询日志或执行以下操作:

In order to check whether a collection field was loaded I would either check the database query logs or do the following:

@PersistenceContext private EntityManager em;
.....
Person person = em.find(Person.class, 1L);//Person entity has a OneToMany relationship to entity Address
em.detach(person);
person.getAddresses().size();//if the Address are now not fetched, it the call should  throw an error

这篇关于JPA fetchType.Lazy无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆