2012-03-23 107 views
2

我在刪除另一個表引用的記錄時遇到問題。JPA級聯刪除

這是一個代碼示例(簡單的場景):

@Entity 
@Table(name = "user") 
public class User 
{ 
    @Id 
    @GeneratedValue(generator="user_id_seq", strategy = GenerationType.SEQUENCE) 
    @SequenceGenerator(name="user_id_seq", sequenceName="user_id_seq") 
    @Column(name = "id", nullable = false) 
    private int id; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "user") 
    private Set<UserLog> userLogSet; 

    // Other attributes 
    // Getters/setters 
} 

@Entity 
@Table(name = "user_log") 
public class UserLog 
{ 
    @Id 
    @GeneratedValue(generator="user_log_id_seq", strategy = GenerationType.SEQUENCE) 
    @SequenceGenerator(name="user_log_id_seq", sequenceName="user_log_id_seq") 
    @Column(name = "id", nullable = false) 
    private int id; 

    @ManyToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name = "user_id", nullable = false) 
    private User user; 

    // Other attributes 
    // Getters/setters 
} 

每當我試着從「用戶」表中刪除的記錄,我得到以下錯誤和PostgreSQL:

ERROR: update or delete on table "user" violates foreign key constraint "fk228a019fd2495d20" on table "user_log"
Detail: Key (id)=(5) is still referenced from table "user_log".

我在做什麼錯?

謝謝!

更新:我試過編碼一個小例子,它可以找到here。使用Tomcat啓動應用程序後,會自動創建數據庫模式(請檢查/src/main/webapp/WEB-INF/jdbc.properties中的連接詳細信息)。當您訪問http://localhost:8080時,一些數據將被插入到數據庫中。如果我嘗試刪除在student表中引用的任何teacher(使用phpPgAdmin),則會出現類似上面的錯誤。

回答

1

您的映射似乎是錯誤的。

用戶可以有許多用戶日誌我猜。

另外@OneToMany應該在集合上,例如java.util.Set。 您放置的級聯在用戶日誌中,如果您對用戶日誌的實例進行操作而不是用戶操作,則會發生這種情況。

據我瞭解更改映射如下。

@Entity 
@Table(name = "user") 
public class User 
{ 
    @Id 
    @GeneratedValue(generator="user_id_seq", strategy = GenerationType.SEQUENCE) 
    @SequenceGenerator(name="user_id_seq", sequenceName="user_id_seq") 
    @Column(name = "id", nullable = false) 
    private int id; 

    @OneToMany(cascade = CascadeType.ALL,mappedBy="user") 
    private Set<UserLog> userLogs; 

    // Other attributes 
    // Getters/setters 
} 


@Entity 
@Table(name = "user_log") 
public class UserLog 
{ 
    @Id 
    @GeneratedValue(generator="user_log_id_seq", strategy = GenerationType.SEQUENCE) 
    @SequenceGenerator(name="user_log_id_seq", sequenceName="user_log_id_seq") 
    @Column(name = "id", nullable = false) 
    private int id; 

    @ManyToOne 
    @JoinColumn(name = "user_id", nullable = false) 
    private User user; 

    // Other attributes 
    // Getters/setters 
} 

我想你想要刪除用戶及其所有的用戶日誌只需刪除用戶和離開用戶日誌沒有任何意義。

希望這會有所幫助。

更新:

Cascades as annotated in entity classes are managed by ORM, not if you externally try to delete them from external tools like phpPgAdmin.

+0

謝謝@ gbagga - 在madth3問題中看到我的評論,我剛剛在這裏發佈了這個例子。現在問題是我不需要'User'類中的'Set',它是強制性的嗎?無論如何要避免它? – satoshi 2012-03-24 22:33:08

+0

@satoshi它不是強制使用Set,它的基本使用使得重複對象不會最終收集到對象中。如果您有興趣,請看@ hibernate [docs](http://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/collections.html) – 2012-03-26 09:50:45

+0

謝謝@gbagga。不幸的是,即使使用您的解決方案,我也面臨同樣的問題JPA/Hibernate應該在PostgreSQL中創建索引嗎?或者所有級聯操作都由ORM管理?謝謝。 – satoshi 2012-03-26 11:02:49

0

你的映射是錯誤的,OneToMany應該在User適用於UserLog的集合。請參閱examples

+0

對不起,你說得對。在我正在使用的代碼中,我使用'ManyToOne',在這裏發佈一個示例時我感到困惑。 (編輯原始問題) – satoshi 2012-03-24 22:31:31