1

我正在使用 JPA/休眠。我注意到当我持久化一个新对象时,我必须查找引用字段。例如,如果我与 Person 和 Address 是一对一的关系。我希望每个地址只指一个人。而且我知道Person 的主键,我仍然需要对 Person 进行查找以保留地址。

@Transactional
public void saveAddressFor( Long personId, <adddress_details> ) {
   Address address = new Address();
   address.setOwner( em.getReference( Person.class, personId ) );
   address.setAddress( <address_details> );
   em.persist( address );
}

我希望因为我知道通过使用#getReference 的Person PKEY,我不必仅仅为了获取它的PKEY 以在插入时进行设置而查找它。但是当我检查 SQL 跟踪时,我发现在事务结束时它实际上会在执行 INSERT 之前查找 Person。

有没有办法避免这种查找?这不是什么大不了的事,只是没有必要,如果可能的话,我想摆脱这些。

4

2 回答 2

0

你的用法是正确的。通常getReference()只会给你一个参考对象而不去数据库。

如果您真的看到它从 DB 加载,很有可能在您的代码中,您访问了person的方法/属性,导致 Hibernate 执行延迟获取。(还有另一种可能是 Hibernate 的错误,但我会说机会很低)

于 2013-08-26T01:29:28.397 回答
0

对于以下休眠属性,这是不可能的:

        <property name="hibernate.jdbc.batch_size" value="150"/>
        <property name="hibernate.order_inserts" value ="true"/>

为了排序插入,出于某种原因,Hibernate 将遍历它所持久的对象的所有实体字段(即使 CascadeType 为 NONE)并在每个字段上调用 ​​#hashCode。调用 #hashCode 将导致从数据库加载引用代理。

对于 4.2.4.Final,您可以在 ActionQueue.java 第 799 行中看到调用 #findBatchNumber 的代码。#findBatchNumber 的违规行号是 856,其中调用了此代码:

       Integer associationBatchNumber = entityBatchNumber.get( value );

在这种情况下,“值”将是 Person 引用。这会导致在其上调用#hashCode,这将需要从数据库中加载它。

于 2013-08-26T18:31:46.627 回答