Hibernate和JAXB注释发生冲突

时间:2014-07-11 14:49:31

标签: java xml hibernate jaxb

我对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注释变量。

知道我的问题可能是什么?

2 个答案:

答案 0 :(得分:1)

当JAXB编写XML时,它会遍历整个数据结构,包括所有关系。 Hibernate正在使用延迟加载。当您使用JAXB创建XML时,您需要确保您的实体已附加到活动的hibernate会话。这允许hibernate执行所需的查询,以便在JAXB请求时填充数据结构的延迟加载部分。

答案 1 :(得分:0)

有两个解决方案可以合并,以便最好地控制编组。

  • 提供一个AccessorFactory,它将创建一个自定义Accessor。在此Accessor中,您可以覆盖

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);

  • 第二个解决方案是覆盖JAXB的AnnotationReader,这样你就可以返回你想要的注释,具体取决于Class,Field等......所以你可以返回XmlTransient注释,如果你不希望你的对象是整理。 这是这样做的:

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,以便根据对象的上下文和内容修改编组。