一尘不染

JPA辅助表为只读视图-Hibernate仍尝试插入行

hibernate

我有以下实体:

@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正在执行插入视图:

insert into VIEW_TWO (ONE_ID) values (?)

它忽略了不可更新和不可插入的列 进度 (这很好),并且仍在尝试插入 ONE_ID
列的值。据我所知,注解@PrimaryKeyJoinColumn将选定的列标记为 insertable = false 和updatable =
false

如何防止hibernate将行插入到辅助表(视图)中?


阅读 283

收藏
2020-06-20

共1个答案

一尘不染

据我所知,注释将@PrimaryKeyJoinColumn选定的列标记为insertable = false和updatable = false。

我认为情况并非如此:@SecondaryTable当记录是实际表而不是视图时,如何将记录插入到中?

由于没有@SecondaryTable@PrimarykeyJoinColumn有防止插入的一种手段那么这样看来,原来的解决方案是行不通的,而且需要进行选择。

一种选择是将VIEW_TWO映射为,@Entity并以级联选项设置为none CPBracket@OneToOne关系链接到您的课程。

@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注释。

@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中都对此进行了重新讨论,并且可以将视图作为a
@SecondaryTable而无需插入: 如果您具有正确的映射

场景1

加载实体以进行编辑,并且不要触摸映射到辅助表的任何字段。没有更新发布到辅助表

方案2

创建并保存一个新实体,并且不要设置任何映射到辅助表的字段。没有为辅助表发出插入

情况3

创建或更新实体,该实体包括映射到辅助表的字段,并且该字段被标记为insertable = false和updateable = false。的插入
到二次表仅取得了ID字段-the行为报道,在原来的问题。

原始问题中的映射问题在于,辅助表字段是原始类型,因此在保存新实体时,Hibernate确实认为必须将记录写入值为零的辅助表。

@Column(name="progress", table="VIEW_TWO", updatable = false, insertable = false)
private int progress = 0;

然后,解决方案是将原语替换为相应的包装器类型,并将其保留为null。然后,在保存新记录时,没有任何内容可写入辅助表,并且不会进行插入:

@Column(name="progress", table="VIEW_TWO")
private Integer progress;
2020-06-20