[英]Persist Tables with parent-child relation between two different schema in Spring Data JPA
[英]Error while deleting data from table (self referencing table with parent-child relation) in spring jpa
我有一個與自身有層次關系的實體 class 名稱注釋。
@Entity
@Table(name = "comment")
public class Comment implements java.io.Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "document", nullable = false)
private Document document;
@Column(name = "threadid")
private String threadId;
@Column(name = "code")
private String code;
@Column(name = "content")
private String content;
@Column(name = "authorid")
private String authorId;
@Column(name = "timestamp")
private String timeStamp;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parentcomment")
private ContractComment parentComment;
}
我想刪除文檔的所有評論,但是當我使用 JpaRepository 使用以下查詢時
"delete from Comment where document.id = :documentId"
它給出了以下錯誤。
Cannot delete or update a parent row: a foreign key constraint fails (`comment`, CONSTRAINT `fk_comment_parentcomment` FOREIGN KEY (`parentcomment`) REFERENCES `comment` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
我嘗試了這 3 種方法,但總是遇到同樣的錯誤。
@OneToOne(fetch = FetchType.LAZY, cascade=CascadeType.ALL)
@JoinColumn(name = "parentcomment")
private ContractComment parentComment;
@OneToOne(fetch = FetchType.LAZY, cascade=CascadeType.REMOVE)
@JoinColumn(name = "parentcomment")
private ContractComment parentComment;
@OneToOne(fetch = FetchType.LAZY, orphanRemoval=true)
@JoinColumn(name = "parentcomment")
private ContractComment parentComment;
您需要添加@OneToOne(fetch = FetchType.LAZY, cascade=CascadeType.REMOVE)
而不是@OneToOne(fetch = FetchType.LAZY, cascade=CascadeType=REMOVE)
使用 CriteriaQueries 來處理您的實體,而不是直接 JPQL 查詢。 CriteriaQuery 可能如下所示:
public void deleteComments(Long documentId) {
CriteriaBuilder cb = this.em.getCriteriaBuilder();
// create delete
CriteriaDelete<Comment> delete = cb.
createCriteriaDelete(Comment.class);
// set the root class
Root root = delete.from(Comment.class);
// set where clause
delete.where(cb.equal(root.get(Comment_.document).get(Document_.id), documentId));
// perform update
this.em.createQuery(delete).executeUpdate();
}
Comment_
class 可用於獲取“評論”實體的所有“列”,因此首先從評論中獲取文檔( root.get(Comment_.document)
),然后獲取文檔的 ID( ...get(Document_.id)
) 並將其與您的參數進行比較。
Criteria Queries 與 JPQL 字符串有點不同,但它們的優點是編譯器可以幫助您在數據庫中實現更改(而 JPQL 查詢只會引發運行時錯誤)
如果您不想使用這樣的查詢,您始終可以在Document
class 中實現deleteComments
方法。 然后你獲取 Document 並讓 entityManager 處理刪除:
Document doc = entityManager.find(Document.class, documentId);
// and in the Document class:
public void deleteComments(){
this.comments.stream.forEach( comment-> comment.delete());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.