JPA 辅助表作为只读视图 - 休眠仍然尝试插入行 [英] JPA secondary table as read only view - hibernate still tries to insert rows

查看:19
本文介绍了JPA 辅助表作为只读视图 - 休眠仍然尝试插入行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下实体:

@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=falseupdatable=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屋!

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