Dem*_*urg 2 mapping hibernate jpa view
这类似于带有继承的 JPA 映射视图和表,但由于接受的答案不能满足我,我决定提出自己的问题。
我有一个基础类,它包含所有实体的公共字段
@MappedSuperclass
@Access(AccessType.FIELD)
public abstract class CommonFields{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
(...)
}
Run Code Online (Sandbox Code Playgroud)
假设我有一个名为 Table 的实体
@Entity
@Table(name = "my_table")
public class Table extends CommonFields{
(..)
}
Run Code Online (Sandbox Code Playgroud)
这对我来说非常有效。我创建了视图,它将一列添加到my_table. 我是这样映射的:
@Immutable
@Entity
@Table(name = "my_table_plus_view")
public class TableView extends Table{
(..)
}
Run Code Online (Sandbox Code Playgroud)
TableView是只读的。这很简单Table带有用于演示目的的附加信息。
此应用程序在 Tomcat 和 Postgres DB 上运行。服务器启动时没有错误,但是当我尝试从视图中获取所有记录时,我收到一个错误,即我的Table不包含DTYPE列。我知道它是什么以及它是如何工作的,但因为我不需要它,所以我不想要它。
我想像Table现在一样读/写我的,但我不知道如何映射我的TableViewJPA 查询可以使用它。我做了一些努力,InheritanceType但没有成功。如果我从Tableto复制所有字段,TableView那么我的应用程序将按预期运行,但这不适合我。如何映射我的视图以便我可以使用继承?
您可以将一个实体映射到 2 个表(或者在您的情况下是一个表和一个视图)。您可以使用@SecondaryTable. 视图的列然后成为实体表的属性,可以像其他任何列一样进行查询。
为了确保不变性,您可以标记可以使用insertable和updatable属性的列@Column。
@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;
}
Run Code Online (Sandbox Code Playgroud)
https://en.wikibooks.org/wiki/Java_Persistence/Tables#Multiple_tables
在这种情况下,您的应用程序只处理一个实体。
另一种方法是创建一个指向视图的新实体,并使用@OneToOne. 只要这种关系始终存在(即标记为optional=false),那么这种方法的好处是仅按需加载视图数据,而使用该@SecondaryTable选项将在每次加载时执行连接。您模型的客户端仍然只能处理一个实体,因为您不需要将第二个实体暴露给外界:
@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;
}
Run Code Online (Sandbox Code Playgroud)
在另一种情况下,您可以使用上面尝试过的继承。然后,您的应用程序将公开 2 个实体 Table 和 TableView。由于您有 2 个单独的表,因此您需要表明您想要使用 Joined 继承策略。这是您的代码中缺少的一点:
https://en.wikibooks.org/wiki/Java_Persistence/Inheritance#Joined.2C_Multiple_Table_Inheritance
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@Table(name = "my_table")
public class Table extends CommonFields{
}
@Entity
@Table(name = "my_table_plus_view")
public class TableView extends Table{
}
Run Code Online (Sandbox Code Playgroud)
使用 Joined 策略,Hibernate 不需要鉴别器列。
| 归档时间: |
|
| 查看次数: |
3683 次 |
| 最近记录: |