我有以下实体:
@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将行插入到辅助表(视图)中?
据我所知,注释将@PrimaryKeyJoinColumn选定的列标记为insertable = false和updatable = false。
@PrimaryKeyJoinColumn
我认为情况并非如此:@SecondaryTable当记录是实际表而不是视图时,如何将记录插入到中?
@SecondaryTable
由于没有@SecondaryTable或@PrimarykeyJoinColumn有防止插入的一种手段那么这样看来,原来的解决方案是行不通的,而且需要进行选择。
@PrimarykeyJoinColumn
一种选择是将VIEW_TWO映射为,@Entity并以级联选项设置为none CPBracket的@OneToOne关系链接到您的课程。
@Entity
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注释。
@Formula
@Entity @Table(name = "ONE") public class CpBracket { @Formula("native sql query") private int someValue; }
我在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;