Hibernate多对一删除只有子

时间:2016-03-17 11:17:40

标签: java hibernate

许多类似的主题在哪里,但我仍然无法自己处理,抱歉。

所以,我有" Bank" 这是" Office" 的父母。
我正在尝试删除单个Office,但之后我会删除父银行的所有办事处。 这是代码:
银行

@Entity
@Table(name = "BANKS")
public class Bank {
    public Bank() {
    }

    public Bank(String name) {
        this.name = name;
    }

    @Id
    @Column(name = "ID")
    @GeneratedValue
    private int id;

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

    @OneToMany(mappedBy = "bank", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @JoinColumn(name = "BANK_ID")
    private List<Office> officeList;

办公室

@Entity
@Table(name = "OFFICES")
public class Office {
    public Office() {
    }

    public Office(String city, String address, String workingHours, Bank bank) {
        this.city = city;
        this.address = address;
        this.workingHours = workingHours;
        this.bank = bank;
    }

    @Id
    @Column(name = "ID")
    @GeneratedValue
    private int id;

        @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
    @JoinColumn(name = "BANK_ID")
    private Bank bank;

    @Column(name = "CITY")
    private String city;

    @Column(name = "ADDRESS")
    private String address;

    @Column(name = "WORKING_HOURS")
    private String workingHours;

OfficeDAO

@Repository
@Transactional
public class OfficeDAOImpl implements OfficeDAO {

    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public Office getByOffice_ID(int Office_ID) {
        return (Office) sessionFactory.getCurrentSession().get(Office.class, Office_ID);
    }

    @Override
    public List<Office> getAllOffice() {
        Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Office.class);
        return criteria.list();
    }

    @Override
    public int save(Office Office) {
        return (Integer) sessionFactory.getCurrentSession().save(Office);
    }

    @Override
    public void update(Office Office) {
        sessionFactory.getCurrentSession().merge(Office);
    }

    @Override
    public void view(Office Office) {
        sessionFactory.getCurrentSession().merge(Office);
    }

    @Override
    public void delete(int Office_ID) {
        Office s = getByOffice_ID(Office_ID);
        System.out.println("trying to delete" + Office_ID);
        sessionFactory.getCurrentSession().delete(s);
    }

}

Hibernate查询跟踪然后只删除office:

Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from banks where id=?

我做错了什么?任何建议将不胜感激。

更新

如果我从办公室删除 cascade = CascadeType.REMOVE ,则hibernate不会发送任何删除请求。

3 个答案:

答案 0 :(得分:1)

您应该以正确的方式配置CascadeType ...

All - 不是您的最佳选择。试试DETACHREMOVE。它应该有帮助:)

有关CascadeType can be found here的更多信息。

答案 1 :(得分:1)

我发现了这个问题。看起来hibernate在父列表中不能删除子实体,所以只需将其添加到office中的delete方法:

s.getBank().getOfficeList().remove(s);

是的, Cascade.Remove 在办公室不应该存在。

答案 2 :(得分:0)

解释为什么会有这种行为。

BankofficeList的父项,因此,如果我们删除officeList,则删除Bank是有意义的。

@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
@JoinColumn(name = "BANK_ID")
private Bank bank;

此注释意味着Office也是Bank的父项

因此,如果我们删除Office->我们应该删除Bank->我们应该删除BankBank本身的所有办公室。

我们在日志中看到了

Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from banks where id=?  

如果我们有@JoinColumn(与Hibernate 5一起使用),我们也不能在这里使用mappedBy

@OneToMany(mappedBy = "bank", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name = "BANK_ID")
private List<Office> officeList;