PostgreSQL继承与JPA,Hibernate [英] PostgreSQL inheritance with JPA, Hibernate

查看:257
本文介绍了PostgreSQL继承与JPA,Hibernate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  CREATE TABLE答案(
idAnswer SERIAL,
answerContent VARCHAR,
idQuestion INTEGER,
version INTEGER,

CONSTRAINT Answer_idAnswer_PK PRIMARY KEY(idAnswer),
CONSTRAINT Answer_idQuestion_FK FOREIGN KEY(idQuestion)参考文献(idQuestion)
);


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

CONSTRAINT MatchAnswer_idAnswer_PK PRIMARY KEY(idAnswer)
)INHERITS(答案);


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

CONSTRAINT TrueFalseAnswer_idAnswer_PK PRIMARY KEY(idAnswer)
)INHERITS(答案);

我们在Netbeans 7.1.2中使用自动工具对实体进行了映射。
一开始我以为只要添加

就够了。 $ b

  @Entity 
@Table truefalseanswer,catalog =jobfairdb,schema =public)
@XmlRootElement
public class Truefalseanswer extends答案implements Serializable {
private static final

只是延伸,但无法正常运作。
什么是最好的方法呢?先感谢。

解决方案

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的继承扩展和只有查询。



如果你能说服你的JPA实现使用 SELECT ... FROM ONLY subclass_table 当在 InheritanceType.TABLE_PER_CLASS 模式时,它应该与PostgreSQL遗产。它将只看到每个表中的非继承行,并像它们是普通表一样使用它们。您的其他非JPA代码可以继续使用继承功能。我想有可能你可以修改PostgreSQL方言代码为Hibernate做到这一点,但个人我不会去那里,除非我绝对使JPA支持现有的PostgreSQL架构,严重依赖继承。 / p>

we have question about inheritance in PostgreSQL and mapping it as entities in JPA. Our database, and tables we want to map are:

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

And we mapped them for entities using automatic tool in Netbeans 7.1.2. At first I thought it would be enough just to add

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

so just extends, but it didn't work properly. What is the best approach to this? Thanks in advance.

解决方案

JPA's concept of inheritance is based on ordinary tables. It doesn't really "get" the idea of PostgreSQL's table inheritance. That's one of the costs of working with a spec designed to expose the lowest common denominator of features and do so portably.

See this guide for a decent summary of JPA inheritance strategies. Note that in the newer Java 6 JavaDoc for @Inheritance there is a note saying that:

If the Inheritance annotation is not specified or if no inheritance type is specified for an entity class hierarchy, the SINGLE_TABLE mapping strategy is used.

... and if you look at how SINGLE_TABLE works, it's not surprising it doesn't work for you; it's expecting all subclasses to be in one big table with a magic discriminator value.

InheritanceType.TABLE_PER_CLASS is closer to how Pg behaves, but I suspect that the JPA impl will get a bit confused when the base type tables have entries for each entity of a leaf type. It tries to do things like UNION queries across the subclass tables when querying on the superclass, and that could produce odd results - at least duplication if UNION is used and performance issues if it uses UNION ALL. Depending on exactly how the provider implements the strategy it may work at least partially. You'd have to test, and the results would possibly be fairly provider specific.

A really good implementation of PG inheritance support for JPA would probably require JPA provider extensions for a new inheritance strategy that understood the PostgreSQL extensions for inheritance and for ONLY queries.

If you can convince your JPA implementation to use SELECT ... FROM ONLY subclass_table when in InheritanceType.TABLE_PER_CLASS mode then it should inter-operate OK with PostgreSQL inheritance. It would see only the non-inherited rows in each table and work with them as if they were ordinary tables. Your other non-JPA code could then keep using the inheritance features. I guess it's possible you could modify the PostgreSQL dialect code for Hibernate to do this, but personally I wouldn't go there unless I absolutely had to make JPA support existing PostgreSQL schema that relied heavily on inheritance.

这篇关于PostgreSQL继承与JPA,Hibernate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆