带通配符和Hibernate的通用集合

时间:2016-05-19 14:44:13

标签: hibernate generics jpa

在Hibernate映射中使用通配符管理泛型集合的最佳方法是什么? 例如,我有一个ComponentParentComponentChildContainer类。如果我尝试下面的例子,我会收到错误:

Caused by: org.hibernate.AnnotationException: Collection has neither generic type or OneToMany.targetEntity() defined

实体

@Entity
@Inheritance
@DiscriminatorColumn(name = "TYPE")
@Table(name = "COMPONENT")
class abstract ComponentParent {
    private Long id;

    ...
}

@Entity
@DiscriminatorValue(name = "CHILD")
class ComponentChild extends ComponentParent {
    ...
}

@Entity
@Table(name = "CONTAINER")
class abstract Container {
    private Long id;

    @OneToMany
    @JoinColumn(name = "containerId")
    private List<? extends ComponentParent> components;
}

@Entity
@DiscriminatorValue("CONC")
class ConcreteContainer {

    public List<ChildComponents> getComponents() {
        return components;
    }

}

2 个答案:

答案 0 :(得分:1)

为什么要将其保留为“带通配符的通用集合”?当你访问它时,无论如何你都需要有一些逻辑来根据类型来处理每个对象吗?

无法将容器中的组件列表保留为

private List<ComponentParent> components;

根据使用列表的ComponentXXX类型使用策略。

(顺便说一下,我假设类ComponentChild扩展了ComponentParent。)

答案 1 :(得分:0)

我不确定你是否可以使用Hibernate / JPA轻松实现这一点。如果你找到解决方案,我也会感兴趣。

但是,如果由我决定,我可能会做以下事情:

@Entity
@Inheritance
@DiscriminatorColumn(name="xxx")
@Table(name = "CONTAINER")
class abstract Container {
    private Long id;

    abstract public List<? extends ComponentParent> getComponents();
}

@Entity
@DiscriminatorValue("CONC")
class ConcreteContainer {

    @OneToMany
    @JoinColumn(name = "containerId")
    private List<ChildComponents> components;

    @Overrides
    public List<ChildComponents> getComponents() {
        return components;
    }

}

然后可能会有另一个

@Entity
@DiscriminatorValue("CONC2")
class ConcreteContainer2 {

    @OneToMany
    @JoinColumn(name = "containerId")
    private List<OtherComponents> components;

    @Overrides
    public List<OtherComponents> getComponents() {
        return components;
    }

}

其中OtherComponent扩展ComponentParent。