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設置 - 而且您必須實施一項策略,以確定如何處理會話中對象的刪除操作!