有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么要休眠。isPropertyInitialized是否返回true?

我有一个Person类,它有一个名为autos的惰性初始化集合。从数据库中获取person后,我调用了两个hibernate方法,分别名为isInitialized(autos)和isPropertyInitialized(personObject,autos)。第一个显示为false,第二个显示为true。为什么?

@Entity
public class Person {

    @OneToMany(mappedBy="person",fetch=FetchType.LAZY)
    private List<Auto> autos;

}


@Entity
public class Auto {

    @ManyToOne
    @JoinColumn(name = "person_id", nullable = false)
    private Person person;

}

测试代码:

Person p = personRepository.findAll().get(0);     
System.out.println(Hibernate.isInitialized(p.getAutos()));
System.out.println(Hibernate.isPropertyInitialized(p,"autos"));

控制台:

false
true

共 (1) 个答案

  1. # 1 楼答案

    我相信在这种情况下Hibernate.isPropertyInitialized的用法可能是不正确的

    根据documentation,应该使用Hibernate.isPropertyInitialized来验证属性或状态的惰性,例如Person对象的"name"。要验证子实体的惰性,应使用Hibernate.isInitialized

    boolean personInitialized = Hibernate.isInitialized(person);
    
    boolean personBooksInitialized = Hibernate.isInitialized(person.getBooks());
    
    boolean personNameInitialized = Hibernate.isPropertyInitialized(person, "name");
    

    或者最好如文档中所述javax.persistence.PersistenceUtil.isLoaded

    PersistenceUtil persistenceUnitUtil = Persistence.getPersistenceUtil();
    
    boolean personInitialized = persistenceUnitUtil.isLoaded(person);
    
    boolean personBooksInitialized = persistenceUnitUtil.isLoaded(person.getBooks());
    
    boolean personNameInitialized = persistenceUnitUtil.isLoaded(person, "name");
    

    现在为什么会有Hibernate.isPropertyInitialized以及为什么它总是返回true 我认为主要原因是Bytecode enhancement和惰性属性加载

    通常在获取实体时,会加载所有属性,例如"name""age"

    When fetching an entity, all attributes are going to be loaded as well. This is because every entity attribute is implicitly marked with the @Basic annotation whose default fetch policy is FetchType.EAGER. source

    然而,通过字节码增强,我们可以定义哪些属性应该是惰性的。当我们有一些较大的属性(如blob image)时,这很有用。我认为,对于这个特定场景,我们需要Hibernate.isPropertyInitialized

    为什么在你的情况下它总是返回true。如果我们看一下该方法的Java文档,就会发现它期望

    @param proxy The potential proxy
    

    如果它是HibernateProxy,那么将检查它是否未初始化。如果是,您将收到false,因为对于代理的惰性,所有属性都被急切地初始化,因此代理是未初始化的,那么属性也是。另一方面,我们有一个声明

     @return true if the named property of the object is not listed as uninitialized; false otherwise
    

    因此,在您的例子中,您没有使用惰性属性获取机制,也没有传递代理对象,因为Person已经初始化。无法检查属性是否列为未初始化,因此返回true