[英]Using cascade.all in a many-to-many with extra columns association
搜索了很長時間后,我想知道我的代碼是否錯誤,或者在 Hibernate 中是否根本不可能。
我會用一個假的例子來解釋我的問題。 假設我的數據庫中有三個表,post、posttag 和 tag。 一個帖子可以有多個標簽,一個標簽可以用於我的多個帖子,所以這是一個多對多的關聯,但在(posttag)之間的表中還有額外的列。
所以,在我的代碼中,我有 3 個實體和一個 class 作為 posttag 的復合鍵。
郵政實體:
@Entity
@Table(name = "post", catalog = "fakeExample")
public class PostEntity implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "IDPOST", nullable = false)
private Integer idpost;
@OneToMany(mappedBy = "post", targetEntity = PostTagEntity.class, cascade = CascadeType.ALL, orphanRemoval = true)
private List<PostTagEntity> listOfPostTag = new ArrayList<>();
public void setIdpost(Integer idpost)
{
this.idpost = idpost;
}
public Integer getIdpost()
{
return this.idpost;
}
public void setListOfPostTag(List<PostTagEntity> listOfPostTag)
{
if (listOfPostTag != null)
{
this.listOfPostTag.clear();
this.listOfPostTag.addAll(listOfPostTag);
}
}
public List<PostTagEntity> getListOfPostTag()
{
return this.listOfPostTag;
}
}
標簽實體:
@Entity
@Table(name = "tag", catalog = "fakeExample")
public class TagEntity implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "IDTAG", nullable = false)
private Integer idtag;
@OneToMany(mappedBy = "tag", targetEntity = PostTagEntity.class, cascade = CascadeType.ALL, orphanRemoval = true)
private List<PostTagEntity> listOfPostTag = new ArrayList<>();
public void setIdtag(Integer idtag)
{
this.idtag = idtag;
}
public Integer getIdtag()
{
return this.idtag;
}
public void setListOfPostTag(List<PostTagEntity> listOfPostTag)
{
if (listOfPostTag != null)
{
this.listOfPostTag.clear();
this.listOfPostTag.addAll(listOfPostTag);
}
}
public List<PostTagEntity> getListOfPostTag()
{
return this.listOfPostTag;
}
}
PostTagEntity:
@Entity
@Table(name = "posttag", catalog = "fakeExample")
public class PostTagEntity implements Serializable
{
@EmbeddedId
private PostTagEntityKey compositePrimaryKey = new PostTagEntityKey();
@Column(name = "EXTRACOLUMN")
private Integer extraColumn;
@ManyToOne
@JoinColumn(name = "IDPOST", referencedColumnName = "IDPOST", nullable = false)
@MapsId("idpost")
private PostEntity post;
@ManyToOne
@JoinColumn(name = "IDTAG", referencedColumnName = "IDTAG", nullable = false)
@MapsId("idtag")
private TagEntity tag;
public void setIdpost(Integer idpost)
{
this.compositePrimaryKey.setIdpost(idpost);
}
public Integer getIdpost()
{
return this.compositePrimaryKey.getIdpost();
}
public void setIdtag(Integer idtag)
{
this.compositePrimaryKey.setIdtag(idtag);
}
public Integer getIdtag()
{
return this.compositePrimaryKey.getIdtag();
}
public void setExtraColumn(Integer extraColumn)
{
this.extraColumn = extraColumn;
}
public Integer getExtraColumn()
{
return this.extraColumn;
}
public void setPost(PostEntity post)
{
this.post = post;
}
public PostEntity getPost()
{
return this.post;
}
public void setTag(TagEntity tag)
{
this.tag= tag;
}
public TagEntity getTag()
{
return this.tag;
}
}
PostTagEntityKey:
@Embeddable
public class PostTagEntityKey implements Serializable
{
@Column(name = "IDPOST", nullable = false)
private Integer idpost;
@Column(name = "IDTAG", nullable = false)
private Integer idtag;
public PostTagEntityKey()
{
}
public PostTagEntityKey(Integer idpost, Integer idtag)
{
this.idsalle = idsalle;
this.idequipement = idequipement;
}
public void setIdpost(Integer value)
{
this.idpost = value;
}
public Integer getIdpost()
{
return this.idpost;
}
public void setIdtag(Integer value)
{
this.idtag = value;
}
public Integer getIdtag()
{
return this.idtag;
}
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (this.getClass() != obj.getClass())
{
return false;
}
PostTagEntityKey other = (PostTagEntityKey) obj;
if (this.idpost == null ? other.idpost != null : !this.idpost.equals((Object) other.idpost))
{
return false;
}
if (this.idpost == null ? other.idpost != null
: !this.idtag.equals((Object) other.idtag))
{
return false;
}
return true;
}
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((idpost == null) ? 0 : idpost.hashCode());
result = prime * result + ((idtag == null) ? 0 : idtag.hashCode());
return result;
}
}
另外,我使用的是 Spring,所以這里是我進行插入或其他操作時涉及的少數 class。 我不認為問題來自這里,但以防萬一。
郵政服務:
public interface PostService
{
public List<PostEntity> findAll();
public Optional<PostEntity> findById(int var1);
public PostEntity save(PostEntity var1);
public void deleteById(int var1);
}
PostImpl:
@Service
public class PostImpl implements PostService
{
@Autowired
private PostRepository repository;
@Override
public List<PostEntity> findAll()
{
return this.repository.findAll();
}
@Override
public Optional<PostEntity> findById(int id)
{
return this.repository.findById(id);
}
@Override
public PostEntity save(PostEntity toSave)
{
return (PostEntity) this.repository.save(toSave);
}
@Override
public void deleteById(int id)
{
this.repository.deleteById(id);
}
}
后存儲庫:
@Repository
public interface PostRepository extends JpaRepository<PostEntity, Integer>, JpaSpecificationExecutor<PostEntity>, PagingAndSortingRepository<PostEntity, Integer>
{
}
因此,當我需要插入帖子時,我只需使用以下內容:
@Autowired
PostService postService;
public PostEntity createPost(PostEntity post)
{
return this.postService.save(post);
}
對我來說, Hibernate 的預期行為將是:
但是,當我嘗試插入帖子時,出現錯誤。 從我所做的許多測試來看,似乎 Hibernate 成功插入帖子,然后嘗試插入 postTags,但失敗,因為 PostTagEntityKey 中的 idPost 仍然是 null。 我本來希望 Hibernate 使用插入帖子中的 id 更新它。
所以我的問題是 hibernate 可以在我描述的情況下做到這一點嗎? 還是我必須手動完成(不使用級聯模式進行插入/更新)? 解釋可能是復合鍵,雙向,其他東西是不可能的,或者這不是 hibernate 應該做的事情。 我想知道這是否可能,如果是,我做錯了什么?
如果這是不可能的,我想知道如果你甚至不能為像中間表這樣常見的東西做它,那么在級聯中插入東西有什么意義。
我沒有嘗試編寫這個假示例,但我相信它會產生相同的結果,因為我幾乎沒有改變原始示例。 我也跳過了創建 postEntity 的部分,因為在我的例子中它是從 JSON 解析的。 我使用了調試器並嘗試了不同的東西,所以我幾乎可以肯定問題不是來自這里。 每個字段都被填滿,即使是 PostTagEntityKey 中的 idTag。 只是 PostTagEntityKey 中的 idPost 是 null 因為帖子尚未插入。 並且 hibernate 在插入帖子后不會更新它。 我開始相信級聯模式無法更新它,也許就是這樣。
創建PostEntity
時,應在 PostEntity 中使用此方法
private void addPostTag(PostTagEntity postTag){
postTag.setPost(this);
this.listOfPostTag.add(postTag);
}
我認為這將解決您的問題
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.