仅使用主键的 Hibernate 代理加载

标签 hibernate

我们有以下关系:
汽车归个人所有。
一个人可以拥有很多辆车。

这是汽车的映射:

<hibernate-mapping package="fr.recouv.scribe.core.bo">
<class name="Car" table="car">
 <id name="id" column="id_car" unsaved-value="0">
  <generator class="sequence">
    <param name="sequence">car_id_car_seq</param>
  </generator>
</id>
<many-to-one name="person" update="false" column="id_person"  class="Person" /> 
<property 
</class>

我有一个带有此签名的网络服务:

 public void insert(Car car, int idPersonOwner)

我想根据特定人的 ID 插入一辆车。 现在我的代码如下所示:

Car car = new Car();
Person owner = personDao.get(idPersonOwner);
car.setPerson(owner);
carDao.save(car);

personDao.get(idPersonOwner) 的 hibernate 实现看起来像

public Person  get(in idPerson){
return session.get(Person.class, id);
}

此方法的缺点:

  • 即使我只需要从 SQL View 中获取他的 ID,所有 Person 对象都会加载
  • 如果人员映射发生变化(例如延迟加载设置为 false 等),该操作可能会生成超过 2 个查询

我的实际解决方法: 就是直接将外键映射为整数

  <property column="id_person" name="idPerson" />

这个解决方案不是面向对象的,而且不太美观。 如果明天我需要检索汽车的所有者,我必须像以前一样重新映射 person 对象并 update=false

是否可以仅加载给定的人员的代理他的 ID,这将导致查询 验证此人是否存在及其主键,并可选择以惰性模式加载其他字段(如果调用)。

我尝试过 session.load 但这不是解决方案。该对象永远不会为空(没有查询测试他的存在)或者不会抛出异常,直到您访问其他字段 从数据库中实际加载对象。

最佳答案

是的,这正是session.load ( EntityManager.getReference 如果使用 JPA)用于。假设实体存在,它会加载对象的代理。

当然,如果在提交时外键约束因该人实际上不存在而中断,则可能会出现异常。但是,如果其他事务在提交之前删除了该人,您也可以使用 Session.get 来获取它。

如果您确实想检查此人是否存在,请执行仅返回 bool 值(或计数)的专用查询,并在您知道此人存在时使用 Session.load:

Number count = 
    session.createQuery("select count(p.id) from Person p where p.id = :theId")
           .setLong("theId", theId)
           .uniqueResult();
if (count.intValue() > 0) {
    Person p = session.load(Person.class, theId);
}
else {
    // throw exception
}

关于仅使用主键的 Hibernate 代理加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7320023/

相关文章:

java - Hibernate 非主键列的级联更新

java - Hibernate内部连接非主键

java - 传递分离实体以将 Spring 持久化为一对多关系

java - Hibernate外键映射?

java - com.sun.istack.SAXException2 和 javax.xml.bind.JAXBException 异常

java.util.MissingResourceException : Can't find bundle for base name com. sun.org.apache.xerces.internal.impl.msg.SAXMessages,区域设置 en_US

java - Hibernate 4(使用 Atomikos 事务管理器的 Jpa 2.0 + Jta)未将对象保存在 mysql 模式中

hibernate - Grails 1.1 应用程序的集成测试在 Grails 2.0.3 中不起作用。会不会是 GORM 配置问题?

java - Hibernate Envers - 审计实体无法从空的审计表关系中恢复 ID

java - ManyToOne 单向禁用约束