我在父表和子表之间存在关系,其中父表具有单个主键,子表具有复合主键。但是,子表中只有一列被引用到父表中。
我的hibernate类是这样连接的:
父表
@Entity
@Table(name = "snippet")
public class SnippetEntity implements Serializable{
private static final long serialVersionUID = -3220451853395334879L;
@Id
@Column(name = "snpt_id", nullable=false, updatable=false)
@JsonBackReference
private String snippetId;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "cretn_ts")
private Date creationTimeStamp;
@Column(name = "cretn_user_id")
private String creationUserId;
public String getSnippetId() {
return snippetId;
}
public void setSnippetId(String snippetId) {
this.snippetId = snippetId;
}
public Date getCreationTimeStamp() {
return creationTimeStamp;
}
public void setCreationTimeStamp(Date creationTimeStamp) {
this.creationTimeStamp = creationTimeStamp;
}
public String getCreationUserId() {
return creationUserId;
}
public void setCreationUserId(String creationUserId) {
this.creationUserId = creationUserId;
}
@Override
public String toString() {
return "SnippetEntity{" +
"snippetId='" + snippetId + '\'' +
'}';
}
}
子表
@Entity
@Table(name = "snippet_detail")
public class SnippetDetailEntity implements Serializable {
private static final long serialVersionUID = -7470223455753164243L;
@Id
@Column(name = "lang_cd", nullable=false, updatable=false)
private String language;
@Column(name = "snpt_type_cd")
private String snippetType;
@Column(name = "snpt_desc")
private String snippetDescription;
@Column(name = "snpt_txt")
private String snippetText;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "cretn_ts")
private Date creationTimeStamp;
@Column(name = "cretn_user_id")
private String creationUserId;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "updt_ts")
private Date updatedTimeStamp;
@Column(name = "updt_user_id")
private String updatedUserId;
@ManyToOne
@JoinColumn(name="snpt_id")
@JsonManagedReference
private SnippetEntity snippetEntity;
public SnippetDetailEntity() {}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getSnippetType() {
return snippetType;
}
public void setSnippetType(String snippetType) {
this.snippetType = snippetType;
}
public String getSnippetDescription() {
return snippetDescription;
}
public void setSnippetDescription(String snippetDescription) {
this.snippetDescription = snippetDescription;
}
public String getSnippetText() {
return snippetText;
}
public void setSnippetText(String snippetText) {
this.snippetText = snippetText;
}
public Date getCreationTimeStamp() {
return creationTimeStamp;
}
public void setCreationTimeStamp(Date creationTimeStamp) {
this.creationTimeStamp = creationTimeStamp;
}
public String getCreationUserId() {
return creationUserId;
}
public void setCreationUserId(String creationUserId) {
this.creationUserId = creationUserId;
}
public Date getUpdatedTimeStamp() {
return updatedTimeStamp;
}
public void setUpdatedTimeStamp(Date updatedTimeStamp) {
this.updatedTimeStamp = updatedTimeStamp;
}
public String getUpdatedUserId() {
return updatedUserId;
}
public void setUpdatedUserId(String updatedUserId) {
this.updatedUserId = updatedUserId;
}
public SnippetEntity getSnippetEntity() { return snippetEntity; }
public void setSnippetEntity(SnippetEntity snippetEntity) { this.snippetEntity = snippetEntity; }
@Override
public String toString() {
return "SnippetDetailEntity{" +
"language='" + language + '\'' +
", snippetType='" + snippetType + '\'' +
", snippetDescription='" + snippetDescription + '\'' +
", snippetText='" + snippetText + '\'' +
", creationTimeStamp=" + creationTimeStamp +
", creationUserId='" + creationUserId + '\'' +
", updatedTimeStamp=" + updatedTimeStamp +
", updatedUserId='" + updatedUserId + '\'' +
", snippetEntity=" + snippetEntity +
'}';
}
}
获取所有snippet_detail
的电话是:
List<SnippetDetailEntity> snippetEntities = dbService.getAll(SnippetDetailEntity.class);
public <T> List<T> getAll(Class<T> clazz) {
return getSession().createCriteria(clazz).list();
}
snippet_detail
中有378条记录。所以,我的问题是,当我执行一个列表来获取snippet_detail
的所有行时,我从snippet_detail
得到两个唯一的记录(前两个与此表中的主键匹配)并且这些记录是重复的多次。记录总数仍为378,但这378条记录是由多次重复的两个记录组成的。我完全困惑的是,我承认这可能是因为我对hibernate的理解是为什么会发生这种情况?我已阅读了很多帖子,他们都在讨论hibernate做outer join
。我在做什么不对劲?如果是这样,我该怎么做才能解决这个问题?
更新:
通过阅读更多博客和帖子,我意识到我的snippet_detail
中有一个复合键,以及通过hibernate处理它以使用@Embeddable
注释的方法。我创建了一个@Embeddable
类,其中包含snpt_id
和lang_cd
。我修改了snippet_detail
实体类以使用@Embeddable
类。我还将@ManyToOne
联接移动到@Embeddable
类,因为我认为这是我需要指定连接条件的位置(即snpt_id
和snippet_detail
之间的snpt_id
{1}}表的{1}}。
现在,fetch运行正常,但是当我插入snippet
时,我得到一个休眠错误,说它无法执行插入,因为我违反了引用键约束。在我原始帖子中的类中,snippet_detail
位于子类中,在这种情况下,如果记录尚不存在,子表的插入将在父代码表中插入记录在摘录表中。
我的父表类与上面的相同。新的@ManyToOne
类和我的子类被修改为:
@Embeddable
答案 0 :(得分:0)
因此,对于父表具有单个主键的父子关系,child具有复合键,并且当其中一个子键具有返回父表的引用约束时,这对于我。
<强>父强>
@Entity
@Table(name = "snippet")
public class SnippetEntity implements Serializable{
private static final long serialVersionUID = -3220451853395334879L;
@Id
@Column(name = "snpt_id", nullable=false, updatable=false)
private String snippetId;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "cretn_ts")
private Date creationTimeStamp;
@Column(name = "cretn_user_id")
private String creationUserId;
}
儿童的复合键为Embeddable:
@Embeddable
public class SnippetDetailPrimaryEntity implements Serializable{
@Column(name = "snpt_id")
private String snippetId;
@Column(name = "lang_cd")
private String language;
}
儿童强>
@Entity
@Table(name = "snippet_detail")
public class SnippetDetailEntity implements Serializable {
private static final long serialVersionUID = -7470223455753164243L;
@EmbeddedId
private SnippetDetailPrimaryEntity snippetDetailPrimaryEntity;
@Column(name = "snpt_type_cd")
private String snippetType;
@Column(name = "snpt_desc")
private String snippetDescription;
@Column(name = "snpt_txt")
private String snippetText;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "cretn_ts")
private Date creationTimeStamp;
@Column(name = "cretn_user_id")
private String creationUserId;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "updt_ts")
private Date updatedTimeStamp;
@Column(name = "updt_user_id")
private String updatedUserId;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="snpt_id", insertable = false, updatable = false)
private SnippetEntity snippetEntity;
}