我有两个实体:
表活动:
|id|milestone_id|..|
| 1|3 |..|
| 2|3 |..|
类别:
@Entity
@Table(name="activity")
public class Activity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
@ManyToOne(optional = false)
private Milestone milestone;
}
和表里程碑:
|id|..|
| 3|..|
类别:
@Entity
@Table(name="milestone")
public class Milestone implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@Column(nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
@JsonIgnore
@OneToMany(fetch = FetchType.LAZY, mappedBy = "milestone")
private List<Activity> activities = new ArrayList<>();
}
现在,当我删除里程碑3时,我的活动保持不变。但是,milestone_id仍指向已删除的相关里程碑。
现在,当我再次检索活动时,我收到此错误:
javax.persistence.EntityNotFoundException: Unable to find nl.geodan.vergunningen.manager.domain.Milestone with id 3
对我来说似乎很合乎逻辑。
但我想要的是,里程碑无法删除,因为活动表上的milestone_id
为optional = false
。
我错过了什么? 我应该重新加载活动吗?我应该使用某种CascadeType吗?
答案 0 :(得分:2)
您的问题与您的数据库架构有关 - 我已尝试reproducing your problem并且我确定您没有使用应用程序生成的架构,但已经存在一个没有定义外键< / strong>即可。请参阅发生ConstraintViolationException
的output.txt文件。
您可以通过执行正确的SQL
命令将外键添加到数据库中:
ALTER TABLE Activity
ADD FOREIGN KEY (milestone_id)
REFERENCES Milestone(id)
或者只是将spring.jpa.hibernate.ddl-auto
属性(in case of spring boot
)更改为create
。如果您使用原始Spring,那么它将属于Hibernate
本身的属性 - hibernate.hbm2ddl.auto=create
。
如果您没有对架构的访问权限或权限,您可以通过编程方式处理它,但这肯定是解决方法,只是闻起来很糟糕 - 一个解决方案是每次删除Milestone
实体时检查依赖关系,另一个涉及将@PreDelete
监听器放入Milestone
实体:
@PreRemove
private void preRemove() {
if (!activities.isEmpty()) {
throw new LinkedActivityExistsException();
}
}