JPA映射扩展表的视图

时间:2017-02-14 14:39:28

标签: hibernate jpa view mapping

这与JPA mapping views and tables with inheritance类似,但由于接受的答案不满足我,我决定提出自己的问题。

我有一个基础类,它包含所有实体的公共字段

@MappedSuperclass
@Access(AccessType.FIELD)
public abstract class CommonFields{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;
   (...)
}

假设我有一个名为Table的实体

@Entity
@Table(name = "my_table")
public class Table extends CommonFields{
(..)
}

这对我来说很有效。我创建了一个视图,它向my_table添加了一列。我这样绘制了它:

@Immutable
@Entity
@Table(name = "my_table_plus_view")
public class TableView extends Table{
(..)
}

TableView read_only 。这是简单的Table,其中包含用于演示目的的其他信息。

此应用程序在Tomcat和Postgres DB上运行。服务器启动时没有错误,但是当我尝试从视图中获取所有记录时,我收到一条错误消息,表明我的Table不包含DTYPE列。我知道它是什么以及它是如何工作的但是因为我不需要它我不想要它。

我想像现在一样读/写Table,但我不知道如何映射我的TableView,因此JPA查询可以使用它。我做了InheritanceType的一些努力,但没有成功。如果我将所有字段从Table复制到TableView,那么我的应用程序将按预期运行,但这不适合我。如何映射我的视图以便我可以使用继承?

1 个答案:

答案 0 :(得分:1)

您可以将一个实体映射到2个表(或者您的案例中的表和视图)。您可以使用@SecondaryTable。然后,视图的列成为实体表的属性,并且可以像任何其他列一样查询。

为确保不变性,您可以标记列,您可以使用insertable的{​​{1}}和updatable属性。

@Column

https://en.wikibooks.org/wiki/Java_Persistence/Tables#Multiple_tables

在这种情况下,您的应用程序只处理一个实体。

另一种方法是创建一个指向视图的新实体,并使用@Entity @Table(name = "my_table") @SecondaryTable(name = "my_table_plus_view") public class Table extends CommonFields{ @Column(name="col_from_view", table="my_table_plus_view", insertable=false, updatable = false) private String someField; } 从Table映射它。只要此关系始终存在(即标记为@OneToOne),则此方法的好处是仅按需加载视图数据,而使用optional=false选项时,将在每个加载上执行连接。您的模型的客户端仍然只能处理一个实体,因为您不需要将第二个实体暴露给外部世界:

@SecondaryTable

在另一种情况下,您可以像上面尝试过的那样使用继承。然后,您的应用程序将公开2个实体Table和TableView。由于您有2个单独的表,因此需要指明您要使用Joined继承策略。这是您的代码中缺少的一点:

https://en.wikibooks.org/wiki/Java_Persistence/Inheritance#Joined.2C_Multiple_Table_Inheritance

@Entity
@Table(name = "my_table")
public class Table extends CommonFields{

   //can be lazily loaded only when optional = false
   //see: http://stackoverflow.com/questions/17987638/hibernate-one-to-one-lazy-loading-optional-false
   @OneToOne(optional = false)
   @JoinColumn(name = "x")
   private TableView tableView;

   public int getCalculatedValue(){
        return tableView.getCalculatedValue();
   }
}


@Entity
@Table(name = "my_table_plus_view")
public class TableView{

    private int calculatedValue;
}

使用Joined策略,Hibernate不需要鉴别器列。

相关问题