问题描述
我在hibernate中编写了一个函数递归地初始化对象的所有属性,以便加载整个对象图。我有两个复杂的场景需要使用这个
像类别和子类别一样的自我组合对象...
<$ c
@NotNull
@Size(max = 50,message)
public class Category {
@Column(nullable = false,length = 50)
@NotNull
={50})
保护字符串名称;
@ManyToOne(targetEntity = Category.class,fetch = FetchType.LAZY,可选= true)
private类别parentCategory;
$ 2)复杂的对象图,有很多对象可以初始化用过的。
问题是我无法使用预先提取,因为我只需要在选择的情况下使用这个整个对象图,而且我希望有泛化代码,所以不需要编写HQL查询对象。
我为此写了部分代码,
<$ c $ (obj));} public void recursiveInitliaze(Object obj)throws Exception {
if(!Hibernate.isInitialized(obj))
Hibernate.initialize(obj);
PropertyDescriptor [] properties = PropertyUtils.getPropertyDescriptors(obj); (PropertyDescriptor propertyDescriptor:properties)
{
Object origProp = PropertyUtils.getProperty(obj,propertyDescriptor.getName());
if(origProp!= null){
this.recursiveInitliaze(origProp); (item):(Collection)origProp){
this.recursiveInitliaze(item);
}
if(origProp instanceof Collection&& origProp!= null)
}
}
}
}
但它有一个问题,它由于双向关系而结束为方法调用的stackoverflow。所以如何检测是否存在双向关系或是否有更好的方法来实现这一点?
我认为获取配置文件也可以帮助,但如果可能的话,仍然想尝试实现因为在项目的当前阶段配置获取配置文件很困难。
解决方案您可以使用
Hibernate.initialize()
初始化它。我不确定这是否级联。否则,你可以检查instanceof HibernateProxy
,它会给你一个isInitialised属性。
更新:由于初始化不会级联,所以需要像你现在一样遍历树。使用Hashset跟踪您已处理的对象。
i am writing one function in hibernate to recursively initialize all properties of object recursively so whole object graph is loaded.
i have two complex scenarios where i need to use this
1) self composite object like category and sub category ...
@Entity public class Category { @Column(nullable = false, length = 50) @NotNull @Size(max = 50, message = "{50}") protected String name; @ManyToOne(targetEntity = Category.class, fetch = FetchType.LAZY, optional = true) private Category parentCategory; }
2) complex object graph which has lot of object to initialize before it can be used.
problem is i can not use eager fetching because i need this whole object graph only in selective cases, and i want to have generalize code so don't need to write HQL queries for objects.
i have written partial some code for this,
public void recursiveInitliaze(Object obj) throws Exception { if(!Hibernate.isInitialized(obj)) Hibernate.initialize(obj); PropertyDescriptor[] properties = PropertyUtils.getPropertyDescriptors(obj); for (PropertyDescriptor propertyDescriptor : properties) { Object origProp = PropertyUtils.getProperty(obj, propertyDescriptor.getName()); if (origProp != null) { this.recursiveInitliaze(origProp); } if (origProp instanceof Collection && origProp != null) { for (Object item : (Collection) origProp) { this.recursiveInitliaze(item); } } } }
but it has one issue, it ends into stackoverflow for method invocation because of bi-directional relationships. so how to detect there is bidirectional relationship or is there any better way to implement this?
i think fetch profile can also help but still want to try to implement this if possible as configuring fetch profile at current stage of project is difficult.
解决方案you can use
Hibernate.initialize()
on the object to initialise it. I'm not sure if this cascades. Otherwise you could checkinstanceof HibernateProxy
which gives you an isInitialised property.Update: since initialize does not cascade you need to traverse the tree like you do already. Use a Hashset to keep track of objects you already processed.
这篇关于Hibernate递归初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!