2017-10-07 84 views
0

我有一个父表和子表之间的关系,其中,父表具有单个主键并且子表具有复合主键。但是,只有一个子表中的列被引用到父表中。Hibernate ManyToOne和列表问题

enter image description here

我的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(); 
} 

有378个记录snippet_detail。所以,我的问题是,当我做一个列表以获取snippet_detail中的所有行时,我会从snippet_detail获得两个唯一记录(前两个匹配此表上的主键),并且这些记录被重复多次。记录总数仍为378,但这378条记录是由多次复制的两条记录组成的。我完全困惑,我承认这可能是由于我对hibernate的理解,为什么会发生这种情况?我已经阅读了很多帖子,他们都谈论了做一个outer join休眠。我正在做什么错?如果是这样,我该如何解决这个问题?

UPDATE:

通过一些博客和文章中,我意识到,我在我的snippet_detail和方式的组合键来处理与冬眠它使用@Embeddable注释阅读。我创建了@Embeddable类,它具有snpt_idlang_cd。我修改了我的snippet_detail实体类以使用@Embeddable类。我也感动了@ManyToOne加入到@Embeddable类,因为我想这是我需要指定连接条件(即间snippet_detailsnpt_idsnippet表的snpt_id

现在,取精品工程,但是当我插入到snippet_detail时,我得到一个hibernate错误,说它无法执行插入操作,因为我违反了参照键约束。在我原始文章中的类中,@ManyToOne位于子类中,在这种情况下,如果该记录不存在于代码片段表中,那么对子表的插入将在父代码片段表中插入一条记录。

我的父表类与上面相同。新@Embeddable类和我的子类被修改为:

@Embeddable 
public class SnippetDetailPrimaryEntity implements Serializable { 

    @ManyToOne 
    @JoinColumn(name = "snpt_id") 
    private SnippetEntity snippetEntity; 

    @Column(name = "lang_cd") 
    private String language; 
} 

@Entity 
@Table(name = "snippet_detail") 
public class SnippetDetailEntity implements Serializable { 

    @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; 
} 
+0

你的孩子谈论两个ID表!只有一个我能看到? –

+0

@AtimeneNazim'snpt_id'和'lang_cd'是我的子表的主键。 –

+0

由于父对象上的manytoone映射关系,我没有在我的子类hibernate类中定义snpt_id。 –

回答

0

因此,对于父子关系下父表中有一个主键,孩子有一个复合键,当孩子的关键之一具有引用约束返回给父对象,这对我来说是有效的。

家长

@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 
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; 
}