0

我想要做的(使用Hibernate)在PostgreSQL的以下内容:ALTER TABLE添加ON DELETE CASCADE声明

ALTER TABLE fruits ADD CONSTRAINTS id ON DELETE CASCADE; 

很显然,我上面的代码不工作,所以我要寻找正确的说法。

如果我不能做到这一点,那么如何了解以下信息:

我有一组数据在我的表fruitsfruits中的id字段被表grapes用作外键。我需要删除fruits中的特定行,并且希望删除级联到grapes,并删除grapes中具有指定id的所有条目。我怎么做?

delete from fruits where id = 1 cascade; 

注意:我不想在grape中做一个连接并删除相应的数据。这只是一个例子。在实际应用中,大量表格取决于fruits

因为我使用Hibernate的情况下,当我使用删除语句,可以休眠帮助做到这一点?
或者我可以用PostgreSQL中的信息模式或系统目录来做到这一点吗?

回答

1

我找到了答案:

//in Fruit object 
    @OneToMany(mappedBy = "fruit", orphanRemoval=true) 
    private List<Grape> grapes; 

    //in Grape object 
    @OneToOne 
    private Fruit fruit; 
1

这是一种单向的父母 - 子女关系,您希望在父母上进行更改,以便级联到孩子,但反之亦然。使用注释,我们可以做到这一点。在fruits实体:

@Cascade(value = { org.hibernate.annotations.CascadeType.ALL, 
    org.hibernate.annotations.CascadeType.DELETE_ORPHAN }) 
@OneToMany(fetch = FetchType.LAZY, mappedBy = "fruit") 
public Set<Grape> getGrapes() { 
    return grapes; 
} 

在“葡萄”实体:

@ManyToOne(fetch = FetchType.LAZY) 
@JoinColumn(name = "fruit_id") 
public Fruit getFruit() { 
    return fruit; 
} 

当您更新或删除父fruit,此更改会自动级联到grape孩子。

+0

在水果POJO我必须创建一个字段'葡萄'像'私人设置葡萄;'没有注释?孩子对父母也一样吗? – user1467855 2012-07-18 18:00:49

+0

是的。以上是对获得者的注释;你仍然需要这些字段 – atrain 2012-07-18 18:09:34

+0

在回来之前,我试图自己做很多事情,只是为了看看是否有可能有效的帖子版本。但它没有奏效。首先它抱怨'无法确定类型为:java.util.Set,在表:Fruit,列(葡萄)';那么当我在'Set 葡萄'字段中添加'@ ManyToOne'时,它会说缺少表格Fruit_Grape。仍然感谢张贴。 – user1467855 2012-07-19 20:29:07

4

您所描述的是使用ON DELETE CASCADE选项的教科书foreign key constraint

SQL您可以在场景中创建表时grapes隐含创建:

CREATE TABLE grapes (
    grape_id int PRIMARY KEY 
    fruit_id int REFERENCES fruits(fruit_id) ON DELETE CASCADE 
); 

或者,您可以稍后将其添加:

ALTER TABLE grapes 
ADD CONSTRAINT grapes_fruit_id_fkey FOREIGN KEY (fruit_id) 
REFERENCES fruits (fruit_id) ON DELETE CASCADE; 

你不编辑系统直接为此目录 - 你几乎没有做过!这就是上面所说的DDL陈述。

请注意,外键约束要求引用列(您的案例中的fruits.fruit_id)具有唯一索引或主索引,并强制执行referential integrity

0

动机

这并没有为我工作,我设置

<property name="show_sql">true</property> 

和输出没有说明像...ON DELETE CASCADE...什么。

我发现了另一个解决方案,它为我工作:

让我们假设你有一个作家的一个类和作者的书类,你想自动删除,只要你删除作者(通过休眠的所有书籍,SQL - 查询,...),并有理由不能(总是)通过session.delete()删除。

可能:

session.createSQLQuery("DELETE FROM author").executeUpdate(); 

解决方案

所以您笔者类可能是这样的:

@Entity 
@Table(name = "author") 
public class Author { 

    @Id 
    @GeneratedValue(generator = "increment") 
    @GenericGenerator(name = "increment", strategy = "increment") 
    @Column(name = "ID") 
    private Integer id; 

    @Column(name = "NAME") 
    private String name; 

    @OneToMany(mappedBy = "author") 
    private Set<Book> books; 
... 

和类书看起来是这样的:

@Entity 
@Table(name = "book") 
public class Book { 

    @Id 
    @GeneratedValue(generator = "increment") 
    @GenericGenerator(name = "increment", strategy = "increment") 
    @Column(name = "ID") 
    private Integer id; 

    @Column(name = "TITLE") 
    private String title; 

    @ManyToOne 
    @JoinColumn(name = "AUTHOR_ID", foreignKey = @ForeignKey(name = "FK_BOOK_author_AUTHOR_ID")) 
    private Author author; 
... 

诀窍是使用

foreignKey = @ForeignKey(name = "FK_BOOK_author_AUTHOR_ID") 

来命名你自己的外键约束,然后添加

<property name="hibernate.hbm2ddl.import_files">update.sql</property> 

的hibernate.cfg.xml(不要忘记休眠。 hbm2ddl.auto)。该update.sql则包含了表约束更新:

ALTER TABLE `book` DROP FOREIGN KEY `FK_BOOK_author_AUTHOR_ID`; 
ALTER TABLE `book` ADD CONSTRAINT `FK_BOOK_author_AUTHOR_ID` FOREIGN KEY (`AUTHOR_ID`) REFERENCES `author`(`ID`) ON DELETE CASCADE; 

,因为Hibernate总是能降/改变约束条件,因为它知道约束的名字 - 你也应该检查@Cascade设置 - 而且您必须实施一项策略,以确定如何处理会话中对象的删除操作!