2017-04-21 130 views
0

刪除父實體時,我也想從數據庫中刪除關聯的子實體。我試圖使用級聯刪除,如下所示,但我必須做一些不正確的事情。刪除父實體時未刪除子實體

當調用父實體對象上的remove時,我收到錯誤消息:「實體仍在數據庫中的其他地方引用」。我可以確認實體在數據庫中其他位置引用的唯一位置在下面的兩個表中(如果我手動刪除數據庫中的子行,父級上的移除調用可以正常工作)。我一直在閱讀關於實體對象,並在過去的9個小時嘗試不同的東西。我究竟做錯了什麼?

這裏是我的父表:

@Entity 
@Table(name = "TURTLE_LOOKUP") 
public class TurtleLookup implements Serializable 
{ 

@Basic(optional = false) 
@Column(name = "TURTLEID") 
private int turtleid; 

@Basic(optional = false) 
@Column(name = "TURTLE") 
private String turtle; 

@OneToMany(mappedBy = "turtleType", cascade = CascadeType.REMOVE) 
List<TurtleReview> turtleReviews; 

... 
} 

這裏是我的子表:

@Entity 
@Table(name = "TURTLE_REVIEW") 
public class TurtleReview implements Serializable 
{ 

@Column(name = "TURTLE_REVIEW_ID") 
private int turtleReviewId; 

@Column(name = "TURTLE_YEAR") 
private int turtleYear; 

@ManyToOne(cascade = CascadeType.REMOVE, optional = false) 
@JoinColumn(name = "TURTLE_ID", referencedColumnName = "TURTLEID") 
private TurtleLookup turtleType; 

@Column(name = "IS_COMPLETE") 
private short isComplete; 

... 
} 

編輯/ UPDATE:

如果我改變CascadeType.REMOVE到CascadeType.ALL時,刪除父TurtleLookup實體對象時,TurtleReview實體從數據庫中成功刪除。但是,當調用下面的函數來創建一個新的TurtleReview實體對象時,JPA會嘗試向數據庫中插入一個新的TurtleLookup實體,該實例拋出異常:「Entry已經駐留在數據庫中。以下是創建新的TurtleReview實體時執行的代碼。

public void setDatasetReviewComplete(TurtleLookup turtle, Short year, boolean isComplete) 
{ 
TurtleReview turtleReview = getTurtleReview(turtle, year); 
if (turtleReview == null) 
{ 
turtleReview = new TurtleReview(); 
turtleReview.setTurtleYear(year) 
turtleReview.setTurtleType(new a.b.entity.TurtleLookup(turtle.getId(), turtle.getValue())); 
} 
turtleReview.setIsComplete(isComplete ? (short)1 : 0); 
entityManager.persist(turtleReview); 
} 

回答

0

嘗試改變級聯價值全部或全部刪除孤兒

@OneToMany(mappedBy = "turtleType", cascade = CascadeType.REMOVE) 
List<TurtleReview> turtleReviews; 

... 
} 
+0

當我更改爲CascadeType.ALL時,刪除子對象的作品,但是,創建新的TurtleReview條目時,我收到錯誤消息「條目已駐留在數據庫中」。通過調試JPA/Entity框架創建的SQL語句,我可以看到它試圖在TURTLE_LOOKUP表中插入一個新行,但它不應該是這樣。 – Mitchell

+0

您應該刪除turtlleReview實體上turtletype字段的級聯,以避免在保存turtlereview對象時創建turtlelookup。 – OTM

0

嘗試使用休眠@Cascade註釋:

@Cascade(value = CascadeType.ALL) 
@OneToOne(mappedBy = "turtleReview") // mappedBy name of TurtleRewiew object field in TurtleLookup entity class 
private TurtleLookup turtleType; 

如果你們的關係是oneToOne你不能有一對多到另一邊,你不能有List<TurtleReview>。如果您的關係是oneToMany,那麼您的實體將是例如:

@Entity 
@Table(name = "TURTLE_LOOKUP") 
public class TurtleLookup implements Serializable 
{ 

@Basic(optional = false) 
@Column(name = "TURTLEID") 
private int turtleid; 

@Basic(optional = false) 
@Column(name = "TURTLE") 
private String turtle; 

@OneToMany(mappedBy = "turtleType") // or add cascade = javax.persistence.CascadeType.ALL and remove @Cascade if you are not using hibernate 
@Cascade(value = CascadeType.ALL) 
List<TurtleReview> turtleReviews; 

... 
} 


@Entity 
@Table(name = "TURTLE_REVIEW") 
public class TurtleReview implements Serializable 
{ 

@Column(name = "TURTLE_REVIEW_ID") 
private int turtleReviewId; 

@Column(name = "TURTLE_YEAR") 
private int turtleYear; 

@ManyToOne 
@JoinColumn(name = "TURTLE_ID", referencedColumnName = "TURTLEID") 
private TurtleLookup turtleType; 

@Column(name = "IS_COMPLETE") 
private short isComplete; 

... 
} 
+0

我不明白。爲什麼我不能在另一邊有OneToMany,爲什麼我不能有List ? TurtleLookup可以有許多TurtleReviews,但TurtleReview只能有一個TurtleLookup。 – Mitchell

+0

是的,你可以在TurtleLookup一邊有OneToMany和List ,但在TurtleReview一邊你必須有ManyToOne(不是一對一) - 這意味着TurtleLookup可以有很多TurtleReviews,TurtleReview可以有一個TurtleLookup – paun90

+0

有道理。我改變了它,並且在創建子實體時,我仍然遇到JPA嘗試創建新父實體的問題。 – Mitchell

0

您的域模型可能存在問題,這是問題中遺漏的一部分。你可能有圓形的瀑布?如果你有一個級聯循環,其中一些是CascadeType.REMOVE,有些是CascadeType.PERSIST,那麼Hibernate(不確定其他JPA實現)只會在你調用remove()方法時做....什麼也不做。沒有錯誤或異常消息。