13

我正在尝试 的示例fetchType.Lazy,但是在调试代码时,它似乎fetchType.Lazy不起作用。

实体 bean:地址

在区字段上添加了带有属性 fetch=fetchType.Lazy 的注释 @Basic。

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

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

4

3 回答 3

13

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

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-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
于 2013-09-09T08:11:48.123 回答
0

确保您已启用编织。

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving

于 2013-09-09T14:04:10.420 回答
0

要在 JPA 中初始化 laze,您需要调用一个 jar 库并启动它,如果是使用 maven 或手动 por 示例,如果您需要 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

于 2017-05-09T16:05:24.057 回答