JPA没有生成“on delete set null”FK限制

我有两个相关的分支JPA注释。 报警和状态。 一个警报可以有一个状态。

我需要的是能够删除一个状态并将空值“传播”到该状态中已被删除的警报。

也就是说,我需要将外键定义为“ on delete set null ”。

@Entity public class Alarm { @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="sequence") @SequenceGenerator(name="sequence", sequenceName="alarm_pk_seq") private Integer id; @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name="idStatus") private Status status; // get/set } @Entity public class Status { @Id @Column(name="idStatus") private Integer id; private String description; // get/set } 

例:

之前:

 STATUS id description 1 new 2 assigned 3 closed ALARMS id status 1 1 2 2 3 2 

之后(删除id = 2的状态)

 STATUS id description 1 new 3 closed ALARMS id status 1 1 2 NULL 3 NULL 

我正在使用Hibernate和PostgreSQL,从源代码自动生成数据库。 我尝试过每一种可能的CascadeType都没有成功。

代码有什么问题吗? 用JPA可以做到吗?

只需使用Hibernate注释添加:

 @OnDelete(action=OnDeleteAction.CASCADE) 

生成外键为:“ON UPDATE NO ACTION ON DELETE CASCADE;”

但是没有动作= OnDeleteAction.SET_NULL

而且,如果可能的话,我不喜欢将我的代码绑定到Hibernate(但如果它有效,我可以忍受它)。

这个主题讨论它。 我不敢相信JPA(或Hibernate扩展)中没有一个简单的方法来生成外键。

在您的情况下,您将从类生成数据库。 这意味着您不会将数据库用于其他目的(因为这样做会强制您使用DDL脚本)。 这意味着在数据库或java代码中实现此规则并不重要。

我们也知道Hibernate会在一个人删除一个或多个状态并尝试在没有级联的情况下提交时引用它的情况下引发一个瞬态exception。

此外,将使用外键约束生成数据库。

所有这些意味着必须遵守约束才能使应用程序正常工作。

如果您的实体本身位于jar中,则可以在警报或状态界面中添加瞬态方法,以在遵守规则的同时删除状态。

此外,程序员在使用实体时将被迫遵守规则,否则代码将无法工作。 但是为了使任务更容易,您可以使关系成为双向关系,以便更轻松地跟踪状态中的警报。

如果可以,请使用ondelete拦截器/侦听器将alarm.status属性设置为null。

不知道其他非hibernate实现,但这里是一个JIRA问题,我一直在Hibernate中关注这个问题…

http://opensource.atlassian.com/projects/hibernate/browse/HHH-2707

您确定使用@OneToOne吗? 在我看来,你宁愿使用@ManyToOne(因为状态会受到几个警报的影响):

 @Entity public class Alarm { ... @ManyToOne(cascade=CascadeType.ALL) @JoinColumn(name="idStatus", nullable=true) private Status status; ... } 

OpenJPA有

 @ForeignKey(deleteAction=ForeignKeyAction.NULL) 

但是没有标准的JPA方法来做到这一点(显然Hibernate是不可能的)。

让我想回到JDO。