如何忽略对象引用从休眠中重用?

若昂·佩德罗·施密特

假设我有以下Java ORM映射:

@Entity
public class Person {

  @Id
  @GeneratedValue
  private Long id;

  @OneToOne
  private Address workAddress;

  @OneToOne
  private Address homeAddress;

}

@Entity
public class Address {

  @Id
  @GeneratedValue
  private Long id;

}

假设给定Person实例是使用相同的持久化Address实例创建的例如:

@Transactional
public void reuseAddressInPerson() {
   Address address = new Address();
   // fill address values
   address = em.persist(address);
   Person person = new Person();
   person.workAddress = address;
   person.homeAddress = address;
   em.persist(person);
}

基于此,当我person使用休眠方式加载该持久化对象时workAddress的地址实例homeAddressperson对象中将是相同的引用有一些方法可以使休眠状态address在调用em.find()为每个对象创建新实例

注意:我已经创建了这个示例来说明我的问题,但是在实际情况下,使用克隆(或类似方法)准备该对象是不实际的。

若昂·佩德罗·施密特

显然,hibernate没有提供任何现成的机制来管理实体引用。因此,我找到了使用的方法ObjectOutputStream该引擎需要两个步骤,第一步是从数据库中加载实体并清除持久性上下文,第二步是在对象结构中搜索应该克隆什么实体以驱逐共享引用。为了解释它是如何工作的,我们将使用与问题相同的人员地址模型。

第1步-加载实体

public Person loadProject() {
  // First we load person from database
  Person person = personRepository.getOne(personId);
  // Then we clear the persistence context to evict detached exceptions
  entityManager.clear();
  person = (Person) Hibernate.unproxy(person); // Remove proxies from the object
  // Now we call Step 2 (clone shared references)
  person = entityReferencesService.cloneAddressReferences(person);
  return person;
}

第2步-克隆共享引用


public class EntityReferencesService {
  //...
  public Person cloneAddressReferences(Person person) {
    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream(baos) {
        {
          enableReplaceObject(true); // Allows objects to be replaced during serialization
        }
        @Override
        protected Object replaceObject(Object obj) throws IOException {
          Object replacedObject = obj;
          // This code could be smart to known what entities to clone
          if (obj instanceof Person) {
            Person p = (Person) obj;
            // using apache bean commons
            p.workAddress = SerializationUtils.clone(p.workAddress);
            p.homeAddress = SerializationUtils.clone(p.homeAddress);
          }
          return replacedObject;
        }
      };
      oos.writeObject(person);
      ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
      ObjectInputStream ois = new ObjectInputStream(bais);
      return (Person) ois.readObject();
    } catch (Exception ex) {}
  }
} 

此示例过于简化。但是对于复杂的场景,在该replaceObject方法中,此代码应使用接口或批注来了解哪些实体会克隆。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何重用堆栈中创建的对象

来自分类Dev

如何重用堆栈中创建的对象

来自分类Dev

如何从休眠查询中获取Map对象

来自分类Dev

如何在休眠中隐藏对象属性?

来自分类Dev

如何在Mongoid中为引用的孩子重用相同的类?

来自分类Dev

如何从对象中引用方法

来自分类Dev

休眠中的对象更新

来自分类Dev

迭代从休眠引用游标返回的对象列表

来自分类Dev

如何在SOAPUI属性测试步骤中重用对象

来自分类Dev

如何重用视图来更新Django中的对象?

来自分类Dev

如何重用AFNetworking对象在iOS中返回结果?

来自分类Dev

如何在Perl单元测试中重用模拟对象?

来自分类Dev

如何在 Observable 链中重用对象实例?

来自分类Dev

如何将对象的引用传递给函数以供重用

来自分类Dev

休眠:为列表中的同一对象引用生成不同的(唯一的)ID

来自分类Dev

休眠工具:如何忽略外键?

来自分类Dev

休眠工具:如何忽略外键?

来自分类Dev

重用Twisted中的延迟对象

来自分类Dev

重用Twisted中的延迟对象

来自分类Dev

在反应中重用 const 对象

来自分类Dev

返回休眠中的对象列表

来自分类Dev

对象引用如何在JavaScript中工作

来自分类Dev

如何引用对象数组中的数组元素?

来自分类Dev

如何检索存储在列表中的对象的引用?

来自分类Dev

如何从javascript中的父对象引用变量

来自分类Dev

如何在NSMutableSets中引用对象

来自分类Dev

引用对象如何在Java中工作

来自分类Dev

如何从对象中引用字段

来自分类Dev

如何在事件块中引用“this”对象?