PostgreSQL继承了JPA,Hibernate

Ata*_*ais 5 database postgresql hibernate jpa java-ee

我们对PostgreSQL中的继承有疑问,并将其映射为JPA中的实体.我们想要映射的数据库和表格是:

CREATE TABLE Answer (
    idAnswer SERIAL,
    answerContent VARCHAR,
    idQuestion INTEGER,
    version INTEGER,

    CONSTRAINT Answer_idAnswer_PK PRIMARY KEY (idAnswer),
    CONSTRAINT Answer_idQuestion_FK FOREIGN KEY (idQuestion) REFERENCES Question(idQuestion)
);


CREATE TABLE MatchAnswer (
    matchingAnswer VARCHAR NOT NULL,
    version INTEGER,

    CONSTRAINT MatchAnswer_idAnswer_PK PRIMARY KEY (idAnswer)       
) INHERITS(Answer);


CREATE TABLE TrueFalseAnswer (
    isTrue BOOLEAN NOT NULL,
    version INTEGER,

    CONSTRAINT TrueFalseAnswer_idAnswer_PK PRIMARY KEY (idAnswer)   
) INHERITS(Answer);
Run Code Online (Sandbox Code Playgroud)

我们使用Netbeans 7.1.2中的自动工具为实体映射它们.起初我觉得加入就足够了

@Entity
@Table(name = "truefalseanswer", catalog = "jobfairdb", schema = "public")
@XmlRootElement
public class Truefalseanswer extends Answer implements Serializable {
    private static final 
Run Code Online (Sandbox Code Playgroud)

所以只是扩展,但它没有正常工作.对此最好的方法是什么?提前致谢.

Cra*_*ger 6

JPA的继承概念基于普通表.它并没有真正"获得"PostgreSQL表继承的想法.这是使用旨在揭示功能的最低公分母并且可以轻松实现的规范的成本之一.

有关JPA继承策略的合理摘要,请参阅本指南.请注意,在较新的Java 6 JavaDoc for @Inheritance中有一条说明:

如果未指定继承注释,或者未为实体类层次结构指定继承类型,则使用SINGLE_TABLE映射策略.

......如果你看看SINGLE_TABLE它是如何运作的,那么它对你不起作用就不足为奇了; 它期望所有子类都在一个带有魔术鉴别器值的大表中.

InheritanceType.TABLE_PER_CLASS更接近于Pg的行为,但我怀疑当基类型表具有叶类型的每个实体的条目时,JPA impl会有点混乱.UNION当查询超类时,它会尝试在子类表中执行查询等操作,这可能会产生奇怪的结果 - 如果UNION使用则至少重复,如果使用则会出现性能问题UNION ALL.根据提供者如何实施策略,它可能至少部分地起作用.您必须进行测试,结果可能是特定于提供商的.

对JPA的PG继承支持的一个非常好的实现可能需要JPA提供程序扩展来实现新的继承策略,该策略理解PostgreSQL扩展以进行继承和ONLY查询.

如果你可以说服你的JPA实现SELECT ... FROM ONLY subclass_tableInheritanceType.TABLE_PER_CLASS模式下使用,那么它应该与PostgreSQL继承互操作.它只会看到每个表中的非继承行,并使用它们就好像它们是普通的表一样.然后,您的其他非JPA代码可以继续使用继承功能.我想你可以修改Hibernate的PostgreSQL方言代码来做到这一点,但我个人不会去那里,除非我绝对不得不让JPA支持现有的依赖继承的PostgreSQL架构.