JPA fetchType.Lazy不起作用

时间:2013-09-09 08:00:57

标签: jpa

我正在尝试fetchType.Lazy的示例,但在调试代码时,似乎fetchType.Lazy无效。

实体bean:地址

在区域字段上添加了注释@Basic,其属性为fetch = fetchType.Lazy。

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

    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的方法:

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方法调用之后,当我检查地址对象时,它已经填充了分区字段。

请告诉我是否缺少某些配置或代码本身是否存在问题。

3 个答案:

答案 0 :(得分:11)

问题在于,当在@Basic注释中使用时,应用服务器可以/可以自己决定何时获取数据更好。记录在案here

  

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

@OneToMany - 类似注释根据documentation同样的问题,但在这种情况下,JPA提供者更有可能会考虑FetchType提示。

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

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

查看是否有更改(尽管您的应用程序服务器可以决定始终获取该字段)。

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

@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

答案 1 :(得分:0)

答案 2 :(得分:0)

要在JPA中初始化laze,你需要调用一个jar库并启动它,如果是maven或者手动的例子,如果你需要laze,在maven中使用jar jar de.empulse.eclipselink更多信息http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving/Static_Weaving#Use_the_Maven_plugin

如果你不使用maven,你可以手动启用jar