Hibernate级联删除不按预期方式工作 [英] Hibernate Cascading Delete Not working as expected

查看:124
本文介绍了Hibernate级联删除不按预期方式工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用hibernate 3并尝试删除数据库中的一条记录,并且删除操作不像我所期望的那样。 hibernate模式正在使用(伪代码):

  create table雇主(
employer_id编号(12)主键,
employer_name varchar2(50)
);

create table Employee(
employee_id number(12)primary key,
employee_name varchar2(50),
employer_id number(12)外键引用employer.employer_id not null
);

create table Employee_Roles(
role_id number(12)主键,
employee_id number(12)外键引用employee.employee_id不为null,
角色varchar2(50 )
);

我的hibernate类映射看起来像这样:

  @Entity 
公共类雇主{

@Id
@Column(name =EMPLOYER_ID)
私人长ID;

@Column
私人字符串名称;


@OneToMany(targetEntity = Employee.class,fetch = FetchType.EAGER)
@JoinColumn(name =employer_id)
@Cascade(CascadeType.ALL )
私人套餐<员工>雇员;
}

@Entity
public class Employee {

@ManyToOne(targetEntity = Employer.class)
@JoinColumn(name = 雇主ID)
@Cascade(值= CascadeType.SAVE_UPDATE)
私人雇主雇主;
$ b $ @ @OneToMany(targetEntity = EmployeeRole.class,fetch = FetchType.EAGER)
@JoinColumn(name =employee_id)
@Cascade(CascadeType.ALL)
私人套餐<员工>雇员;
}

@Entity
public class EmployeeRole {

@ManyToOne(targetEntity = Employee.class)
@JoinColumn(name = employee_id)
@Cascade(value = CascadeType.SAVE_UPDATE)
私人雇员雇员;

$ / code>

现在使用这个配置我打电话给:

  getCurrentSession()。delete(someEmployerEntity); 

发生的是:

<$ p $ Hibernate:更新EMPLOYEE set EMPLOYEE_ID = null,其中EMPLOYEE_ID =?
Hibernate:更新EMPLOYEE_ROLE set employee_id = null where employee_id ==?
[2011-04-15 15:59:53,487] JDBCExceptionReporter警告 - SQL错误:-10,SQLState:23502
[2011-04-15 15:59:53,487] JDBCExceptionReporter错误 - 完整性约束违规:NOT NULL检查约束; SYS_CT_10058表:EMPLOYEE_ROLE

并引发异常。由于session.remove(..)调用,我期望的是要删除的雇主记录,以及与雇主相关的所有员工记录以及与删除的员工记录关联的所有EmployeeRole记录。这是一个正确的假设吗?或者我误解了这里的一个关键概念?

解决方案

Cascade all-delete-orphan应该可以解决您的问题。但是,它是Hibernate的一部分,而不是EJB标准。如果你想这样做,而不是被困在供应商的解决方案中,我建议你看看这篇文章



祝你好运!

编辑:遵循您的建议,我将'mappedBy'属性添加到@OneToMany注释中,这似乎是使用inverse =true来指定拥有关系的注释方式。这些关系的相关变化部分如下所示:

  public class Employee {

@OneToMany(targetEntity = EmployeeRole.class,mappedBy =employee,fetch = FetchType.EAGER,cascadeType = CascadeType.ALL)
private Set< EmployeeRole> employeeRoles;


$ b公共类雇主{

@OneToMany(targetEntity = Employee.class,mappedBy =employer,fetch = FetchType.EAGER, cascadeType = CascadeType.ALL)
private Set< Employee>雇员;
}


I am using hibernate 3 and attempting to delete a record in the database, and the delete is not working as I would expect. The schema hibernate is working against (in pseudocode):

create table Employer(
    employer_id number(12) primary key,
    employer_name varchar2(50)
);

create table Employee(
    employee_id number(12) primary key,
    employee_name varchar2(50),
    employer_id number(12) foreign key references employer.employer_id not null
);

create table Employee_Roles(
    role_id number(12) primary key,
    employee_id number(12) foreign key references employee.employee_id not null,
    role varchar2(50)
);

My hibernate class mappings look something like:

@Entity
public class Employer{

    @Id
    @Column(name = "EMPLOYER_ID")
    private long id;

    @Column
    private String name;


    @OneToMany(targetEntity = Employee.class, fetch = FetchType.EAGER)
    @JoinColumn(name = "employer_id")
    @Cascade(CascadeType.ALL)
    private Set<Employee> employees;
}

@Entity
public class Employee{

    @ManyToOne(targetEntity = Employer.class)
    @JoinColumn(name = "employer_id")
    @Cascade(value = CascadeType.SAVE_UPDATE)
    private Employer employer;

    @OneToMany(targetEntity = EmployeeRole.class, fetch = FetchType.EAGER)
    @JoinColumn(name = "employee_id")
    @Cascade(CascadeType.ALL)
    private Set<Employee> employees;
}

@Entity
public class EmployeeRole{

    @ManyToOne(targetEntity = Employee.class)
    @JoinColumn(name = "employee_id")
    @Cascade(value = CascadeType.SAVE_UPDATE)
    private Employee employee;
}

Now with this configuration I am calling:

getCurrentSession().delete(someEmployerEntity);

What is occurring is:

Hibernate: update EMPLOYEE set EMPLOYEE_ID=null where EMPLOYEE_ID=?
Hibernate: update EMPLOYEE_ROLE set employee_id=null where employee_id==?
[2011-04-15 15:59:53,487] JDBCExceptionReporter WARN  - SQL Error: -10, SQLState: 23502
[2011-04-15 15:59:53,487] JDBCExceptionReporter ERROR - integrity constraint violation: NOT NULL check constraint; SYS_CT_10058 table: EMPLOYEE_ROLE

and an exception being raised. What I am expecting as a result of the session.remove(..) call is the employer record to be deleted, as well as all employee records associated with the employer and all EmployeeRole records associated with the deleted employee records. Is this a correct assumption? Or am I misunderstanding a key concept here?

解决方案

Cascade all-delete-orphan should solve your problem. However, it is part of Hibernate and not EJB standard. If you want to do it and do not be trapped in your vendors' solution, I would suggest you to have a look to this article.

Good luck!

EDIT: following your suggestions I added the 'mappedBy' attributes to the @OneToMany annotations which seems to be the annotations way of using inverse="true" for specifying the owning relationships. The relevant changed sections of the relationships look like:

public class Employee{

    @OneToMany(targetEntity = EmployeeRole.class, mappedBy="employee", fetch = FetchType.EAGER,  cascadeType=CascadeType.ALL)
    private Set<EmployeeRole> employeeRoles;
}


public class Employer{

    @OneToMany(targetEntity = Employee.class, mappedBy="employer", fetch = FetchType.EAGER, cascadeType=CascadeType.ALL)
    private Set<Employee> employees;
}

这篇关于Hibernate级联删除不按预期方式工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆