嗯,我的疑问非常简单:为了获得最佳性能,建议在我不需要使用的属性中使用始终延迟初始化(这很明显)。所以,想象下面的课程:
@Entity
public class Person{
@Column
private String name;
@ManyToOne(fetch = FetchType.Lazy)
@JoinColumn(name = "id_type")
private TypePerson type;
}
在我的主类中,我调用了没有初始化“type”属性的Person,如下面的那样:
public void init(){
//in this point "type" attribute is not initialized
Person person = dao.find("Select * from Person where id = 12");
//proxys work here to get description of "type" attribute
System.out.println(person.getType().getDescription());
}
因此,我从dataBase获取一个简单的Person对象,并在控制台上打印人的类型。在这一刻,代理CGLIB工作并做你的魔术,一切正常。
但是我在这里提出问题:
1 - 当我请求“getType()”时,Hibernate(或其他机制)在幕后进行SQL查询?例如:“SELECT * FROM TypePerson,其中id = 3”。
如果答案是肯定的:这种获取属性值的方法可能非常痛苦,因为我认为Hibernate每次都会在数据库中进行,以便在幕后获取这些信息。
如果答案为否:如果未从dataBase加载,代理如何知道属性的值?
答案 0 :(得分:3)
致电时
person.getType().getDescription()
如果person
引用尚未初始化的Hibernate代理,则是,它会发出SQL查询以检索目标实体的字段值。
获取属性值的这种方法可能非常痛苦,因为我 认为Hibernate每次都会在数据库中获取这些信息 在幕后。
每个代理只会执行一次。当它第一次出现时,它将在代理上设置一个标志,指示它已初始化,因此底层目标实体具有正确的值。如果加载了所有值,则不需要返回数据库。
这不是Hibernate创建代理的原因,但这是一个很好的阅读:Proxy Pattern。
答案 1 :(得分:1)
getDescription()
返回的代理上调用person.getType()
方法时,它会进入数据库。