2009-01-20 72 views
10

我有两个相关的类JPA注释。警报和状态。一个闹钟可以有一个状态。JPA没有生成“on delete set null”FK的限制

我需要的是能够删除一个状态和“传播”空值是在已删除的状态的报警。

也就是说,我需要将外键定义为“删除集合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 

我使用休眠和PostgreSQL,自动生成所述数据库源代码。我已经尝试过所有可能的CascadeType,但没有成功。

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

回答

0

您确定使用@OneToOne吗? 在我看来,你宁愿使用@ManyToOne(作为状态可以影响到一些警报):

@Entity 
public class Alarm { 
    ... 

    @ManyToOne(cascade=CascadeType.ALL) 
    @JoinColumn(name="idStatus", nullable=true) 
    private Status status; 

    ... 
} 
+0

谢谢。你是对的,我刚刚将它改为ManyToOne关系,并添加了nullable = true参数,但结果仍然是相同的:( – 2009-01-24 16:03:56

3

只需添加,使用Hibernate的注解:

@OnDelete(action=OnDeleteAction.CASCADE) 

产生国外键为:“在DELETE CASCADE上执行UPDATE NO ACTION;”

但没有行动= OnDeleteAction.SET_NULL

而且,我不喜欢扎我的代码到Hibernate(如果可能,但我可以住在一起,如果它的工作原理)。

thread讨论它。我不能相信在JPA(或Hibernate扩展)中没有简单的方法来生成外键。

2

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

我们也知道,Hibernate的将提高瞬态异常在没有级联提交时人会删除一个或多个状态,并试图引用它的情况。

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

所有这一切意味着,约束必须被尊重的应用程序工作。

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

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

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

-1

OpenJPA中有

@ForeignKey(deleteAction=ForeignKeyAction.NULL) 

,但没有标准的JPA方式来做到这一点(显然这是不可能与休眠)。

让我想回到JDO。