Java 如何在hibernate中忽略从加载重用的对象引用?

Java 如何在hibernate中忽略从加载重用的对象引用?,java,hibernate,jpa,Java,Hibernate,Jpa,假设我有以下Java ORM映射: @实体 公共阶层人士{ @身份证 @生成值 私人长id; @奥内托内 私人地址工作地址; @奥内托内 私人地址家庭地址; } @实体 公共课堂演讲{ @身份证 @生成值 私人长id; } 假设给定的Person实例是使用相同的持久化地址创建的。 例如: @Transactional 公共空间重复使用ReadDressInPerson(){ 地址=新地址(); //填充地址值 地址=em.persist(地址); Person=新人(); person.wor

假设我有以下Java ORM映射:

@实体
公共阶层人士{
@身份证
@生成值
私人长id;
@奥内托内
私人地址工作地址;
@奥内托内
私人地址家庭地址;
}
@实体
公共课堂演讲{
@身份证
@生成值
私人长id;
}
假设给定的
Person
实例是使用相同的持久化
地址创建的。
例如:

@Transactional
公共空间重复使用ReadDressInPerson(){
地址=新地址();
//填充地址值
地址=em.persist(地址);
Person=新人();
person.workAddress=地址;
person.homeAddress=地址;
em.person;
}
基于此,当我使用hibernate加载这个持久化的
person
时,
workAddress
homeAddress
的地址实例将与
person
对象中的地址实例相同。 调用
em.find()
时,有一些方法可以让hibernate为每个
地址
对象创建新实例


注意:我创建了这个示例来说明我的问题,但是在实际场景中,使用克隆(或类似的东西)来准备这个对象是不实际的。

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

步骤1-加载实体

公众人物加载项目(){
//首先,我们从数据库中加载person
Person=personRepository.getOne(personId);
//然后清除持久性上下文以排除分离的异常
entityManager.clear();
person=(person)Hibernate.unproxy(person);//从对象中删除代理
//现在我们调用步骤2(克隆共享引用)
person=EntityReferenceService.cloneAddressReferences(person);
返回人;
}
步骤2-克隆共享引用


公共类EntityReferenceService{
//...
公共人物克隆地址引用(个人){
试一试{
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
ObjectOutputStream oos=新的ObjectOutputStream(BAS){
{
enableReplaceObject(true);//允许在序列化期间替换对象
}
@凌驾
受保护对象替换对象(对象obj)引发IOException{
objectreplacedobject=obj;
//此代码可以智能地知道要克隆哪些实体
if(人员的obj实例){
人员p=(人员)obj;
//使用ApacheBeanCommons
p、 workAddress=SerializationUtils.clone(p.workAddress);
p、 homeAddress=SerializationUtils.clone(p.homeAddress);
}
返回替换对象;
}
};
oos.书面对象(人);
ByteArrayInputStream bais=新的ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois=新ObjectInputStream(BAI);
返回(Person)ois.readObject();
}捕获(例外情况除外){}
}
} 

这个例子过于简化了。但是对于复杂的场景,在
replaceObject
方法中,该代码应该使用接口或注释来克隆实体。

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

步骤1-加载实体

公众人物加载项目(){
//首先,我们从数据库中加载person
Person=personRepository.getOne(personId);
//然后清除持久性上下文以排除分离的异常
entityManager.clear();
person=(person)Hibernate.unproxy(person);//从对象中删除代理
//现在我们调用步骤2(克隆共享引用)
person=EntityReferenceService.cloneAddressReferences(person);
返回人;
}
步骤2-克隆共享引用


公共类EntityReferenceService{
//...
公共人物克隆地址引用(个人){
试一试{
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
ObjectOutputStream oos=新的ObjectOutputStream(BAS){
{
enableReplaceObject(true);//允许在序列化期间替换对象
}
@凌驾
受保护对象替换对象(对象obj)引发IOException{
objectreplacedobject=obj;
//此代码可以智能地知道要克隆哪些实体
if(人员的obj实例){
人员p=(人员)obj;
//使用ApacheBeanCommons
p、 workAddress=SerializationUtils.clone(p.workAddress);
p、 homeAddress=SerializationUtils.clone(p.homeAddress);
}
返回替换对象;
}
};
oos.书面对象(人);
ByteArrayInputStream bais=新的ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois=新ObjectInputStream(BAI);
返回(Person)ois.readObject();
}捕获(例外情况除外){}
}
} 

这个例子过于简化了。但是对于复杂的场景,在
replaceObject
方法中,此代码应该使用接口或注释来知道克隆了哪些实体。

您的真实场景是什么,becau