JPA EntityManager remove() 无效

来源:互联网 发布:linux创建oracle实例 编辑:程序博客网 时间:2024/06/14 22:40

上周发现一个问题,删除一条记录的时候发现无法删除,然后排查的时候一行一行定位代码,用的是JPA,删除功能是这样写的:

@Override    public void deleteById(Long id) {    Company company = this.findById(id);    System.out.println("查出来的company: " + company);    em.remove(company);        System.out.println("删除company成功");    }

实际结果是记录并没有删掉,难道是 em.remove(company); 这句没执行吗?也不对,因为后面的print语句都输出了,说明删除操作肯定是执行的,但因为某种原因没有成功。

那么原因在哪里呢?查资料、折腾了一天也没查出来。

后来进行了对比排查,Company 类无法删除,但是Farmer 类却可以,于是观察两者有什么区别,网上查到很多文章说remove(entity)不起作用的话是因为有外键关联,于是开始对比:

首先看数据库表, company 和 farmer表都和town表有多对一关系,通过town_id关联,但在数据库中并没有设置外键,也就是说mysql是不知道的,因此不会进行干涉。

然后看java类,在类中,Company 和 Farmer 确实和Town类设置了多对一关系(Company类和Farmer类都是这样写的):

@ManyToOne    @JoinColumns({            @JoinColumn(name = "TOWN_ID", nullable = false, referencedColumnName = "ID", insertable = false, updatable = false)    })    @JsonIgnore    public Town getTown() {        return town;    }
于是尝试在Company类中删除这部分外键代码,发现报错;

这时,开始接近真相了,于是找出Town类来查看,终于发现问题了:

private String name;    private List<Company> companys = new ArrayList<Company>();    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    @Column(name = "ID")
... ...

@OneToMany(cascade=CascadeType.ALL, mappedBy="town", fetch = FetchType.EAGER)    @OrderColumn(name = "ID")    @JsonIgnorepublic List<Company> getCompanys() {return companys;}


在Town类中,设置了与Company的一对多关联,但是没有和Farmer的关联,所以Farmer能删除,而Company因为和Town有外键关联所以无法删除。

尝试删除了Town类中的Company关联,然后问题解决,Company记录可以正常删除了!



0 0
原创粉丝点击