我是否使用正确的JPA注释来保存我的H2数据库中的实体?

时间:2014-07-10 11:23:22

标签: java hibernate jpa jboss wildfly

我的问题:

@Entity
public class Container {

    @OneToMany(cascade = CascadeType.ALL)
    private List<Element> containedElements;

    public final List<Element> getContainedElements() {
        return containedElements;
    }
}

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Element {
    @ManyToOne(cascade = CascadeType.ALL)
    private Container myContainer;

    public final Container getMyContainer() {
        return myContainer;
    }

    public abstract Object getValue();

    public abstract void setValue(final Object newValue);
}

@Entity
public class StringElement extends Element {
    private String someValue;

    public final Object getValue() {
        return someValue;
    }

    public final void setValue(final Object newValue) {
        someValue = newValue;
    }
}

我有一个容器类,可能包含抽象类Element的许多对象。 我有这个Element类的多个实现,其中一个是StringElement。

使用JPA API(由Hibernate提供)和本地H2数据库以及一个小型测试类,我可以持久化这些类的实体并为它们查询数据库并将它们输出到控制台。

使用Wildfly 8.0(JBoss),JPA API(由Hibernate提供)和Wildfly - &#34;管理&#34; H2数据库,我可以持久化实体,但是当我在数据库中查询一个Container对象时,我无法访问所包含的元素。尝试这样做会导致以下错误:

Caused by: java.lang.NumberFormatException: empty String
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1011)
    at java.lang.Double.parseDouble(Double.java:540)
    at org.h2.value.Value.convertTo(Value.java:846)

我可以在数据库中查询数据库中所有StringElements的列表并解析结果。我可以通过getMyContainer()访问Container。然后,当我尝试通过getContainedElements()。get(0)访问Element时,我再次收到上述错误。

我是否使用了正确的JPA注释?如何在容器中有一个抽象对象列表?

2 个答案:

答案 0 :(得分:0)

@OneToMany注释默认为FetchType.LAZY。

当容器实体不再由持久性上下文管理时,您似乎正在尝试访问containsElements 当容器由持久化上下文管理时(如果要保留FetchType.LAZY)或只是将fetch更改为FetchType.EAGER:

,您必须读取containsElements
@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER )
private List<Element> containedElements;

答案 1 :(得分:0)

我终于可以自己回答:

问题在于多个继承Element的类。或者更确切地说,错误的原因是两个或多个继承自Element的类,每个类都有一个名为 someValue 的属性。问题是每个属性都有不同的基本类型。

对所有元素(及其子类)进行选择会尝试连接两个Element子类的表,然后尝试合并 someValue 列。由于每列具有不同的类型,引擎会为合并列提供某种类型(例如Long),并尝试将其他列中的所有值转换为已决定的类型。

一个数据库引擎合并了列并创建了一个Long列。这导致了上述错误。另一个数据库引擎合并了列并创建了一个Varchar列。这导致没有错误,因为我的所有值都可以很容易地转换为Varchar。