Hibernate注释:一对一onDelete操作无法设置为CASCADE

时间:2012-09-17 07:52:57

标签: database hibernate annotations hibernate-mapping cascade

我想创建两个表USER和USERDETAIL来实现:

  1. USERDETAIL引用了USER表。

  2. USER表上的操作不需要知道USERDEAIL表是否存在。

  3. 这应该是一对一的非双向关系。

    实体类:

    @Entity
    @Table(name="USER")
    public class User implements Serializable{  
        @Id 
        @Column(name="ID")
        @GeneratedValue(generator = "system-uuid") 
        @GenericGenerator(name = "system-uuid", strategy = "uuid")  
        private String id;  
        //...
    }
    
    @Entity
    @Table(name="USERDETAIL")
    public class UserDetail implements Serializable{    
    
        @Id 
        @Column(name="ID")
        @GeneratedValue(generator = "gen") 
        @GenericGenerator(name = "gen", strategy = "foreign",
        parameters = @Parameter(name = "property", value = "user"))
        private String id;
    
        @OneToOne(optional= false , targetEntity=User.class, cascade= CascadeType.ALL)
        @OnDelete(action = OnDeleteAction.CASCADE)
        //@JoinColumn(name="foreign_id",referencedColumnName="ID")
        @PrimaryKeyJoinColumn   
        private User user;  
        //...
    }
    

    这正确地创建了两个表,并且USERDETAIL具有外键约束,其主键是由USER的id引用的。但是,“删除”操作为Restrict,但不是Cascade。因此,我无法删除一行USER。

    我正在使用MySQL Sever 5.1。它似乎不支持删除操作是级联。因为我可以手动删除约束并添加一个设置为on的新约束是cascade并按预期工作。

2 个答案:

答案 0 :(得分:0)

您的代码应为:

@Entity
@Table(name="USER")
public class User implements Serializable{  
    @Id 
    @Column(name="ID")
    @GeneratedValue(generator = "system-uuid") 
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    private String id;  
    //...

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="userdetail_id")
    public UserDetail getUserDetail() {
      ...
    }
}

@Entity
@Table(name="USERDETAIL")
public class UserDetail implements Serializable{    

    @Id 
    @Column(name="ID")
    @GeneratedValue(generator = "gen") 
    @GenericGenerator(name = "gen", strategy = "foreign",
    parameters = @Parameter(name = "property", value = "user"))
    private String id;

    @OneToOne(optional= false , targetEntity=User.class, mappedBy = "userDetail")
    @PrimaryKeyJoinColumn   
    private User user;  
    //...
}

基本上,我建议双向使用,User类是所有者(通过在UserDetail类中使用mappedBy)。这样,当您删除用户时,将删除用户详细信息。

答案 1 :(得分:0)

最后,我已经解决了这个问题。

首先,我遵循http://www.mkyong.com/hibernate/hibernate-one-to-one-relationship-example-annotation/来创建oneToOne映射实体。

但是,当我启动Tomcat时,它总是在映射上抛出NullPointerException。因此,我想出了我的问题实体,除了删除之外似乎工作得很好。

我终于意识到这只是一个hibernate-anoatation导致的错误。然后我使用3.4.0.ga版本并再次关注该链接。通过替换@GeneratedValue(strategy = IDENTITY)(我不知道为什么使用它,hibernate无法创建表)

@GeneratedValue(generator = "system-uuid") 
@GenericGenerator(name = "system-uuid", strategy = "uuid") 

它像我预期的那样工作。

虽然表上没有外键约束,但删除所有者(USER)表确实也可以使用hibernate句柄正确删除子(USERDETAIL)表。

我也不需要担心没有子字段的更新所有者表。 Khue Vu说,mappedBy方实际上没有定义物理映射。 Hibernate非常聪明,不会删除关系。