我对hibernate或JAXB并不是特别熟悉,所以请原谅我,如果我没有很好地解释我的问题。
我正在使用的程序已经设置了一类hibernate实体。我的工作是添加JAXB注释以将变量编组到XML文件中。
@OneToMany(fetch = FetchType.LAZY, mappedBy = "Blah")
@XmlElementWrapper(name = "ListOfThings")
@XmlElement(name = "Thing")
private Set<Stuff> stuff = new HashSet<Stuff>(0);
当我尝试运行程序时,我收到此错误:
org.hibernate.LazyInitializationException:懒得初始化角色集合: package.class ,没有关闭会话或会话
我有3个变量,我使用@XmlElement注释,两个也有@OneToMany注释。 @OneToMany变量都给出了同样的错误,但是当我将它们都设置为瞬态时,程序可以非常好地编译非@TenToMany注释变量。
知道我的问题可能是什么?
答案 0 :(得分:1)
当JAXB编写XML时,它会遍历整个数据结构,包括所有关系。 Hibernate正在使用延迟加载。当您使用JAXB创建XML时,您需要确保您的实体已附加到活动的hibernate会话。这允许hibernate执行所需的查询,以便在JAXB请求时填充数据结构的延迟加载部分。
答案 1 :(得分:0)
有两个解决方案可以合并,以便最好地控制编组。
public abstract ValueT get(BeanT bean) throws AccessorException;
如果pojo未初始化,则返回null:
if (!Hibernate.isInitialized(valueT)) {
return null;
}
请注意,有一种烦人的优化方法:
public Accessor<BeanT,ValueT> optimize(@Nullable JAXBContextImpl context) {
return this;
}
可以替换您的自定义Accessor,具体取决于您覆盖的Accessor(请参阅FieldReflection)。
不要忘记JAXBContext的以下初始化:
HashMap<String, Object> props = new HashMap<String, Object>();
props.put(JAXBRIContext.XMLACCESSORFACTORY_SUPPORT, true);
JAXBContext jaxbContext = JAXBContext.newInstance(new Class[] { clazz }, props);
HashMap<String, Object> props = new HashMap<String, Object>();
props.put(JAXBRIContext.ANNOTATION_READER, new CustomAnnotationReader());
JAXBContext jaxbContext = JAXBContext.newInstance(new Class[] { clazz }, props);
RuntimeInlineAnnotationReader
是最终版,无法覆盖...因此您必须复制代码。
我个人合并了这两个approches,以便根据对象的上下文和内容修改编组。