Java 删除父实体时未删除子实体

Java 删除父实体时未删除子实体,java,jpa,orm,Java,Jpa,Orm,删除父实体时,我还希望删除关联的子实体(从数据库中)。我已经尝试使用下面所示的移除上的级联,但我一定做了一些错误的事情 在父实体对象上调用remove时,我收到错误消息:“该实体仍在数据库的其他位置被引用”。我可以确认数据库中其他地方引用实体的唯一位置是在下面两个表中(如果我从数据库中手动删除子行,则对父行的remove调用可以正常工作)。在过去的9个小时里,我一直在阅读有关实体对象的书籍,并尝试不同的东西。我做错了什么 这是我的父表: @Entity @Table(name = "TURTLE

删除父实体时,我还希望删除关联的子实体(从数据库中)。我已经尝试使用下面所示的移除上的级联,但我一定做了一些错误的事情

在父实体对象上调用remove时,我收到错误消息:“该实体仍在数据库的其他位置被引用”。我可以确认数据库中其他地方引用实体的唯一位置是在下面两个表中(如果我从数据库中手动删除子行,则对父行的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;

...
}
编辑/更新:

如果我将CascadeType.REMOVE更改为CascadeType.ALL,则删除父TurtleLookup实体对象时,TurtleReview实体将从数据库中成功删除。但是,当调用下面的函数来创建一个新的TurtleReview实体对象时,JPA尝试将一个新的TurtleLookup实体插入数据库,这会引发异常:“条目已经驻留在DB.Transaction回滚中”。下面是创建新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);
}

尝试将级联值更改为“全部”或“全部删除孤立项”

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

...
}
@OneToMany(mappedBy=“turtleType”,cascade=CascadeType.REMOVE)
列出套头衫评论;
...
}

尝试使用hibernate
@Cascade
注释:

@Cascade(value = CascadeType.ALL)
@OneToOne(mappedBy = "turtleReview") // mappedBy name of TurtleRewiew object field in TurtleLookup entity class
private TurtleLookup turtleType;
如果你的关系是一对一的,你就不能让另一方有一个配偶,你也不能让
列表
。如果您的关系是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;

...
}
@实体
@表(name=“TURTLE\u LOOKUP”)
公共类TurtleLookup实现了可序列化
{
@基本(可选=假)
@列(name=“TURTLEID”)
私人套头衫;
@基本(可选=假)
@列(name=“海龟”)
私人线龟;
@OneToMany(mappedBy=“turtleType”)//或者添加cascade=javax.persistence.CascadeType.ALL,如果不使用hibernate,则删除@cascade
@级联(值=级联类型.ALL)
列出套头衫评论;
...
}
@实体
@表(name=“TURTLE\u REVIEW”)
公共类TurtleReview实现了可序列化
{
@列(name=“TURTLE\u REVIEW\u ID”)
私人套头衫;
@列(name=“海龟年”)
私人套头衫年;
@许多酮
@JoinColumn(name=“TURTLE\u ID”,referencedColumnName=“TURTLEID”)
私人套头衫;
@列(name=“已完成”)
私人短消息是完全的;
...
}

您的域模型可能存在问题,这是问题中遗漏的一部分。你们可能有环形瀑布吗?如果您有一圈级联,其中一些是CascadeType.REMOVE,一些是CascadeType.PERSIST,那么Hibernate(不确定其他JPA实现)就可以了。。。。调用remove()方法时不执行任何操作。没有错误或异常消息。

当我将两者都更改为CascadeType.ALL时,删除子对象是有效的,但是,在创建新的TurtleReview条目时,我会收到错误消息“条目已驻留在数据库中”。通过调试JPA/Entity框架正在创建的SQL语句,我可以看到它正在尝试在TURTLE_查找表中插入一个新行,而该新行不应该插入。您应该删除turtlereview实体上的cascade on turtletype字段,以避免在保存turtlereview对象时创建turtlelookup。我不理解。为什么我不能在另一边有一个女人,为什么我不能有名单?TurtleLookup可以有许多TurtleReview,但一个TurtleReview只能有一个TurtleLookup。是的,在TurtleLookup一侧可以有一个Omany和List,但在TurtleReview一侧必须有多个Omany(而不是一个Oone)-这意味着TurtleLookup可以有许多TurtleReview,TurtleReview可以有一个TurtleLookup。我更改了它,但仍然存在JPA在创建子实体时尝试创建新父实体的问题。此外,我不能使用@Cascade,也不能导入它。您不能导入,因为您没有hibernate批注的依赖项。您使用JPA,然后需要将
@OneToMany(mappedBy=“turtleType”,cascade=javax.persistence.CascadeType.REMOVE)
@ManyToOne
放到另一边
@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;

...
}