简体   繁体   English

为什么延迟获取无法正常工作JPA

[英]Why Lazy Fetching is not working JPA

i have a hard time understanding the lazy fetching since i does not work for as i read about it in a book, they say that in lazy fetching jpa will load the entities only when they are accessed through geters so i created an Arquillian project to test this concept but it does not work. 我很难理解懒惰的获取,因为我在书中读到它时并没有为此工作,他们说在懒惰的获取中,jpa仅在通过geters访问实体时才加载实体,因此我创建了一个Arquillian项目进行测试这个概念,但是行不通。 here are my two entities 这是我的两个实体

Person

package com.actionbazaar.model;

@Entity
@TableGenerator(
        initialValue = 5,
        name = "PERSON_SEQ",
        table = "PERSON_SEQ_TABLE",
        pkColumnName = "SEQ_NAME",
        pkColumnValue = "PERSON",
        valueColumnName = "SEQ_VALUE")
public class Person implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String fname;
    private String lname;
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", cascade = CascadeType.PERSIST)
    List<Address> addresses;
    //getters and setters 
}

Address 地址

    @Entity
public class Address implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String city;
    private String zip;
    private String street;

    @ManyToOne
    private Person owner;
//getters and setters
}

I have a stateless session bean with this method 我有这种方法的无状态会话bean

    public Person getFirstPerson() {
    Person p = em.find(Person.class, 1);
    em.detach(p);
    //why this call does not create an exception
    p.getAddresses().get(0);
    return p;
}

since i detached the entity before accessing the address the addresses list should be empty and when i hace detached it so it is no longer managed by the entitymanager so i should not get addresses for the person the problem is that i can fetch the addresses of that person even i have lazy fetch for addresses field and detached the entity before accessinbg the addresses field!!!! 由于我在访问地址之前分离了该实体,因此地址列表应该为空,并且当我分离它时,它不再由entitymanager管理,因此我不应该为该人获取地址,问题是我可以获取该地址人甚至我都懒惰地获取地址字段并在访问地址字段之前分离了实体!!!! pleas some have the explanation . 请一些解释。

An other test 另一个测试

Person p= myStatlessSessionBean.getFirstPerson();
myOtherStalessSesionBean.moveAllPeopleToCity("NY");
if(p.getAddresses().get(0).getCity().equals("NY"))
{
  system.out.prinln("person moved");
}
else {
system.out.prinln("person did not move");
} //prompts person did not move

Yeah buddy, you were right. 是的,哥们,你是对的。 You are not doing anything wrong here. 您在这里没有做错任何事情。 I just opened the Pro JPA 2, 2nd edition Book and found this : 我刚刚打开Pro JPA 2第二版Book ,发现了以下内容:

这是快照

You are using glassfish-embedded which is actually causing the problem. 您正在使用嵌入玻璃鱼,这实际上是导致问题的原因。 Your code have no problem. 您的代码没有问题。 As mentioned by the author of the above mentioned book, 正如上述书的作者所提到的,

Some vendors might attempt to resolve the relationship, while others might simply throw an exception or leave the attribute uninitialized. 一些供应商可能尝试解决关系,而其他供应商可能只是抛出异常或使属性未初始化。

So, in your case, the relationship is resolved rather than lazy loading. 因此,在您的情况下,关系得到解决而不是延迟加载。 Just Implement the same example using other vendor and you will not face any problem. 只需使用其他供应商实施相同的示例,您就不会遇到任何问题。 Here using glassfish-embedded, lazyfetch is not working. 在这里使用嵌入的玻璃鱼, 无法进行lazyfetch Otherwise the exception should be thrown, as the variable p is detached. 否则应抛出异常,因为变量p已分离。

Here is the link where i also read this beautiful piece of information 这里是链接在那里我也看到这个美丽的资料片

Here is the snapshot from above link 这是上面链接的快照 快照

You are only detaching the parent entity, Person. 您仅分离父实体Person。 You are not detaching the children entities, Addresses, and when you get addresses, it refers to entities which are still managed by the persistence context. 您没有分离子实体,即地址,当您获得地址时,它是指仍由持久性上下文管理的实体。

If you want the children to be detached as well, you should use CascadeType.DETACH. 如果还希望将子代分离,则应使用CascadeType.DETACH。

You might say, "But my FetchType is set to LAZY!". 您可能会说:“但是我的FetchType设置为LAZY!”。 Just because it's LAZY, doesn't mean the object is null. 仅仅因为它是LAZY,并不意味着该对象为null。 Hibernate returns Proxy objects for collection types, and once you try to access them, it will populate their values. Hibernate返回集合类型的Proxy对象,一旦尝试访问它们,它将填充它们的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM