JPA 辅助表作为只读视图 - 休眠仍然尝试插入行 [英] JPA secondary table as read only view - hibernate still tries to insert rows
问题描述
我有以下实体:
@Entity
@Table(name = "ONE")
@SecondaryTable(name = "VIEW_TWO", pkJoinColumns = @PrimaryKeyJoinColumn(name="ONE_ID"))
public class CpBracket {
@Id
private Long id;
@Column(name="progress", table="VIEW_TWO", updatable = false, insertable = false)
private int progress = 0;
(...)
}
如您所见,该实体使用表 ONE 和(只读)视图 VIEW_TWO.当我持久化实体时,hibernate 正在执行插入到视图中:
As you see, this entity uses table ONE and (read only) view VIEW_TWO. When I'm persisting the entity, hibernate is performing insert into view:
insert into VIEW_TWO (ONE_ID) values (?)
它忽略了不可更新和不可插入的列进度(很好),它仍在尝试插入 ONE_ID 列的值.据我所知,注释@PrimaryKeyJoinColumn 将所选列标记为 insertable=false 和 updatable=false.
It is ignoring the non-updatable and non-insertable column progress (that's good) and it is still trying to insert value of ONE_ID column. As far as I know, the annotation @PrimaryKeyJoinColumn marks selected column as insertable=false and updatable=false.
如何防止 Hibernate 将行插入辅助表(视图)?
How can I prevent hibernate from inserting rows into secondary table (view)?
推荐答案
据我所知,注解
@PrimaryKeyJoinColumn
标记选中列为可插入=假和可更新=假.
As far as I know, the annotation
@PrimaryKeyJoinColumn
marks selected column as insertable=false and updatable=false.
我不相信会出现这种情况:那么当 @SecondaryTable
是一个实际的表而不是一个视图时,我们如何将记录插入到其中?
I do not believe this can be the case: how then do we get records inserted into the @SecondaryTable
when it is an actual table rather than a view?
由于 @SecondaryTable
或 @PrimarykeyJoinColumn
都没有阻止插入的方法,因此您的原始解决方案似乎不起作用,需要替代方案.
As neither @SecondaryTable
or @PrimarykeyJoinColumn
have a means to prevent insert then it would appear that your original solution is not going to work and an alternative is required.
一种选择是将 VIEW_TWO 映射为 @Entity
并链接到您的类 CPBracket
作为 @OneToOne
关系,并将级联选项设置为没有.
One option is to map VIEW_TWO as an @Entity
and link to your class CPBracket
as a @OneToOne
relationship with cascade options set to none.
@Entity
@Table(name ="VIEW_TWO")
private CpBracketSummaryData(){
}
@Entity
@Table(name = "ONE")
public class CpBracket {
@OneToOne
@PrimaryKeyJoinColumn
private CPBracketSummaryData summaryData;
public int getSomeValue(){
return summaryData.getSomeValue();
}
}
第二种选择是使用非 JPA 兼容的、特定于 Hibernate 的 @Formula
注释.
The second option would be to use the non JPA compliant, Hibernate specific @Formula
annotation.
@Entity
@Table(name = "ONE")
public class CpBracket {
@Formula("native sql query")
private int someValue;
}
2016 年 10 月更新
我在 Hibernate 4.3.10.Final 和 5.1.0.Final 中都重新审视了这个,并且可以将视图作为 @SecondaryTable
而不插入:如果你有正确的映射.
场景一
加载实体以进行编辑,不要触摸映射到辅助表的任何字段.二级表没有更新
Load an entity for edit and do not touch any fields mapped to the secondary table. No update is issued to the secondary table
场景 2
创建并保存新实体,不要设置任何映射到辅助表的字段.次表没有插入插入
Create and save a new entity and do not set any fields mapped to the secondary table. No insert is issued for the secondary table
场景 3
创建或更新包含映射到辅助表的字段的实体,并且该字段被标记为可插入 = 假和可更新 = 假.仅针对 ID 字段对辅助表进行插入 - 原始问题中报告的行为.
Create or update an entity including a field mapped to a secondary table and where this field is marked as insertable = false and updateable = false. An insert is made to the secondary table only for the ID field -the behaviour reported in the original question.
原始问题中的映射问题在于辅助表字段是原始类型,因此在保存新实体时,Hibernate 确实认为必须将记录写入辅助表,其值为 0.
The issue with the mapping in the original question is the fact that the secondary table field is a primitive type and therefore when saving a new entity Hibernate does think a record has to be written to the secondary table with a value of zero.
@Column(name="progress", table="VIEW_TWO", updatable = false, insertable = false)
private int progress = 0;
然后的解决方案是用相应的包装器类型替换原语并将它们保留为空.然后当保存一条新记录时,没有什么可以写入辅助表,也不会进行插入:
The solution then is to replace primitives with the corresponding wrapper types and leave them as null. Then when saving a new record there is nothing to write to the secondary table and no insert will be made:
@Column(name="progress", table="VIEW_TWO")
private Integer progress;
这篇关于JPA 辅助表作为只读视图 - 休眠仍然尝试插入行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!