我試圖解決這個問題已經有一段時間了,但我還沒有實作100%的解決。 首先,我必須描述我的問題。我正在開發一個餐廳應用程式,在物體中,我有一個物體Ingredient,正如你所知,Ingredient可以由其他具有特定數量的Ingredient組成。所以我創建了一個帶有嵌入式標識的物體SubIngredient。
為了保持子成分串列,我嘗試了層疊和孤兒移除的組合,每個組合對某些操作有效,但對其他操作無效。
我開始使用CascadeType.ALL,新的子成分成功地從@OneToMany屬性中持久化了,但是如果我試圖從子成分串列中洗掉一個子成分并保存,就會出現這個錯誤。
java.lang.StackOverflowError: null at com.mysql.cj.NativeSession.execSQL(NativeSession.java:1109) ~[mysql-connector-java-8.0.23.jar:8.0.23] ......
我在網上尋找解決方案,我發現我必須使用orphanremoval = true,我試過了,但直到我把級聯從CascadeType.ALL改為CascadeType.PERSIST,它才發揮作用。但是,這使得新的SubIngredient的持久化出現了錯誤
。原因是:javax.persistence.EntityNotFoundException。Unable to find com.example.Resto.domain.SubIngredient with id com.example.Resto.domain.SubIngredientKey@51b11186........
這些是我的特征:
@Entity。
public class Ingredient {
@Id
@GeneratedValue( strategy = GenerationType.IDENTITY)
@Column(name="ID")
private long id;
@NotNull
@Column(unique=true)
private String name;
private String photoContentType;
@Lob
private byte[] photo;
@JsonIgnoreProperties({"photoContentType","photo")
@ManyToOne[/span
private IngredientType ingredientType。
@OneToMany(mappedBy = "embId. ingredientId", fetch = FetchType.EAGER。
cascade = CascadeType.ALL /* orphanRemoval = true, cascade = CascadeType.PERSIST*/ )
private Set<SubIngredient> subIngredients = new HashSet<SubIngredient>()。
getters和setters.....
而且
@Entity
@AssociationOverrides({
@AssociationOverride(name = "embId. ingredientId",
joinColumns = @JoinColumn(name = "ING_ID")。
@AssociationOverride(name = "embId.subIngredientId"。
joinColumns = @JoinColumn(name = "SUB_ING_ID"/span>)) })
public class SubIngredient {
@EmbeddedId[/span
private SubIngredientKey embId = new SubIngredientKey()。
private double quantity;
獲取器 和 設定器....
而且
@Embeddable
public class SubIngredientKey implements Serializable{
@ManyToOne(cascade = CascadeType.ALL)
private Ingredient ingredientId;
@ManyToOne(cascade = CascadeType.ALL)
private Ingredient subIngredientId;
獲取器和設定器...
uj5u.com熱心網友回復:
堆疊溢位的發生是因為你使用了Set<>與Hibernate。當Hibernate從你的DB中檢索物體時,它將用每個物體填充Set<>。為此,hashode/equals將被用來確定該物體是否已經存在于Set<>中。默認情況下,當你呼叫Ingredient的hashcode時,這種情況會發生:
hashcode Ingredient -> hashcode SubIngredient -> hashcode Ingredient
這將導致無限次呼叫hashcode方法。這就是為什么你有一個堆疊溢位錯誤。
同樣的事情也會發生在equals/toString。
所以為了避免這樣的問題,最好是覆寫hashcode、equals和toString。
uj5u.com熱心網友回復:
我已經解決了這個問題,對可能的物體做了一些修改,并覆寫了equals/hashcode方法,謝謝Pilpo。
@Embeddable。
public class SubIngredientKey implements Serializable{
private Long ingredientId;
private Long subIngredientId;
/***。
* @return the ingredientId
*/
@Override
public int hashCode() {
return Objects.hash( ingredientId, subIngredientId)。
}
@Override.
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (! (obj instanceof SubIngredientKey) {
return false;
}
SubIngredientKey other = (SubIngredientKey) obj;
return Objects.equals( ingredientId, other.ingredientId)
&& Objects.equals(subIngredientId, other.subIngredientId) 。
}
}
@Entity; }
public class SubIngredient {
@EmbeddedId {
private SubIngredientKey embId = new SubIngredientKey()。
@ManyToOne(fetch = FetchType.lazy)
@MapsId(" ingredientId")
private Ingredient成分。
@ManyToOne(fetch = FetchType.lazy)
@MapsId("subIngredientId")
private Ingredient subIngredient;
private double quantity;
@JsonIgnore
public SubIngredientKey getId() {
return embId。
}
public void setId(SubIngredientKey id) {
this.embId = id;
}
@JsonIgnoreProperties({"subIngredients", "photo","photoContentType"," ingredientType"})
public Ingredient getIngredient() {
return ingredient;
}
public void setIngredient(Ingredient ingredients) {
this.ingredient = ingredient;
}
@JsonIgnoreProperties({"subIngredients", "photo","photoContentType"," ingredientType"})
public Ingredient getSubIngredient() {
return subIngredient;
}
public void setSubIngredient(Ingredient subIngredient) {
this.subIngredient = subIngredient;
}
public double getQuantity(/span>) {
return quantity;
}
public void setQuantity(double quantity) {
this.quantity = quantity。
}
@Override.
public String toString(){
return "subIngredient=" getSubIngredient()。 getName() " , quantity= " getQuantity();
}
@Override
public int hashCode() {
return Objects.hash( ingredient,subIngredient)。
}
@Override.
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (! (obj instanceof SubIngredient) {
return false;
}
SubIngredient other = (SubIngredient) obj;
return Objects.equals(成分,其他。 ingredient) && Objects.equals(subIngredient, other.subIngredient) 。
}
}
@Entity; }
public class Ingredient {
@Id
@GeneratedValue( strategy = GenerationType.IDENTITY)
@Column(name="ID")
private long id;
@NotNull
@Column(unique=true)
private String name;
private String photoContentType;
@Lob
private byte[] photo;
@JsonIgnoreProperties({"photoContentType","photo")
@ManyToOne[/span
private IngredientType ingredientType。
@OneToMany(mappedBy = "embId. ingredientId", fetch = FetchType.EAGER, cascade =
CascadeType.ALL, orphanRemoval = true)
private Set<SubIngredient> subIngredients = new HashSet<SubIngredient>()。
public long getId() {
return id。
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return this.name。
}
public void setName(String name) {
this.name = name;
}
public String getPhotoContentType() {
return photoContentType。
}
public void setPhotoContentType(String photoContentType) {
this.photoContentType = photoContentType;
}
public byte[] getPhoto(/span>) {
return photo;
}
public void setPhoto(byte[] photo) {
this.photo = photo;
}
public IngredientType getIngredientType() {
return this.ingredientType;
}
public void setIngredientType(IngredientType ingredientsType) {
this.ingredientType = ingredientType。
}
public Set<SubIngredient> getSubIngredient() {
return subIngredients;
}
public void setSubIngredients(>Set<SubIngredient> subIngredients) {
this.subIngredients = subIngredients;
}
public void addSubIngredient(SubIngredient subIngredient) {
this.subIngredients.add(subIngredient)。
}
@Override.
public String toString(){
String subIngsText = ""/span>;
for(var subIngredient:this.subIngredients) {
subIngsText = subIngsText ", "/span> subIngredient.toString();
}
return "{id=" id ",name=" name ", ingredients=" subIngsText "}。
}
@Override; }
public int hashCode() {
return Objects.hash(name)。
}
@Override.
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (! (obj instanceof Ingredient) {
return false;
}
Ingredient other = (Ingredient) obj;
return Objects.equals(name, other.name)。
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/309844.html
標籤:
上一篇:如何訪問SQLite表?
