春季引导。如何正确删除@ManyToOne子集合

时间:2019-04-12 10:46:05

标签: spring hibernate

有一个“应该是”奇怪的问题,但是当我有父母和孩子时,如何正确处理此案:

@Entity
public class Parent {
   @Id
   private long id;

   @OneToMany(mappedBy = "parent")
   @Cascade(values = {CascadeType.PERSIST, CascadeType.REMOVE});// mysql db
   private List<Child> children = new LinkedList<Child>();// yea, this can be removed
}


@Entity
public class Child {
   @Id
   private long id;

   @ManyToOne
   @JoinColumn
   private Parent parent;
}

这是我通常想要做的:

public class SomeService {
    @Autowired
    private ParentDao parentDao;

    @Autowired
    private ChildDao childDao;

    @Transactional
    public void removeChildren(Parent parent) {
        // attempts #1
        childDao.removeAll(parent.getChildren());

        // attempts #2
        for(Child ch: parent.getChildren()) {childDao.removeById(ch.getId());}

        // attempts #3
        parent.getChildren().clear();
        parentDao.save(parent);
   }

启用了休眠sql日志记录后,我发现没有任何高级尝试甚至尝试做出delete语句-仅“从父表中选择...”。而且,当然,所有条目都会保留。

DAO从JpaRepository<Parent\Child, Long>扩展。

对于“ Id”案例,我什至尝试通过id验证现有条目,是的-该条目存在。

我同时具有Spring Boot的“ 1.4.1 RELEASE”和“ 2.1.4 RELEASE”版本。有人可以告诉我我在做什么错吗? (删除父级作品和级联作品均应删除)。


输出示例:

@Override
    @Transactional
    public void cleanResourcesForParent(SessionConfig cfg) {
        logger.info("Removing resources for parent {}", cfg);

        for (Resource r : cfg.getResources()) {
            logger.info(">>> {}", r);
            logger.info("exist? {}", resourceDao.existsById(r.getId()));
            logger.info("Attempt 1");
            resourceDao.deleteById(r.getId());
            logger.info("Attempt 2");
            resourceDao.delete(r);
        }
        logger.info("Attempt 3");
        resourceDao.deleteAll(cfg.getResources());

        logger.info("flush");
        resourceDao.flush();
        /*
         * cfg.getResources().clear(); sessionConfigDao.saveAndFlush(cfg);
         */
    }

父-SessionConfig,子-资源(在数据库中映射为session_config_resource)。

输出:

Hibernate: select resources0_.parent_id as parent_i3_10_0_, resources0_.id as id1_10_0_, resources0_.id as id1_10_1_, resources0_.line as line2_10_1_, resources0_.parent_id as parent_i3_10_1_ from session_config_resource resources0_ where resources0_.parent_id=?
2019-04-12 14:35:35 INFO  [scheduling-1] SessionConfigServiceImpl.resolveSessionConfig: Updating C:\IpPhoneAutomation\ATA\ConfigSession\GLAnton\Sanity450LyncContactPictureConfig.tcl. Sync file date: 1545995407645, file last modif: 1545995407645
2019-04-12 14:35:35 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: Removing resources for parent SessionConfig [id=1096, configName=Sanity450LyncContactPictureConfig.tcl, modified=1545995407645, resources=6]
2019-04-12 14:35:35 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: >>> Resource [id=1097, parent=SessionConfig [id=1096, configName=Sanity450LyncContactPictureConfig.tcl, modified=1545995407645, resources=6], line=0]
Hibernate: select count(*) as col_0_0_ from session_config_resource resource0_ where resource0_.id=?
2019-04-12 14:35:35 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: exist? true
2019-04-12 14:35:35 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: Attempt 1
Hibernate: select resource0_.id as id1_10_0_, resource0_.line as line2_10_0_, resource0_.parent_id as parent_i3_10_0_, sessioncon1_.id as id1_9_1_, sessioncon1_.config_name as config_n2_9_1_, sessioncon1_.modified as modified3_9_1_ from session_config_resource resource0_ left outer join session_config sessioncon1_ on resource0_.parent_id=sessioncon1_.id where resource0_.id=?
Hibernate: select resources0_.parent_id as parent_i3_10_0_, resources0_.id as id1_10_0_, resources0_.id as id1_10_1_, resources0_.line as line2_10_1_, resources0_.parent_id as parent_i3_10_1_ from session_config_resource resources0_ where resources0_.parent_id=?
2019-04-12 14:35:35 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: Attempt 2
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
2019-04-12 14:35:35 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: >>> Resource [id=1098, parent=SessionConfig [id=1096, configName=Sanity450LyncContactPictureConfig.tcl, modified=1545995407645, resources=6], line=1]
Hibernate: insert into session_config_resource (line, parent_id, id) values (?, ?, ?)
Hibernate: delete from session_config_resource where id=?
Hibernate: select count(*) as col_0_0_ from session_config_resource resource0_ where resource0_.id=?
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: exist? true
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: Attempt 1
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: Attempt 2
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: >>> Resource [id=1099, parent=SessionConfig [id=1096, configName=Sanity450LyncContactPictureConfig.tcl, modified=1545995407645, resources=6], line=2]
Hibernate: insert into session_config_resource (line, parent_id, id) values (?, ?, ?)
Hibernate: delete from session_config_resource where id=?
Hibernate: select count(*) as col_0_0_ from session_config_resource resource0_ where resource0_.id=?
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: exist? true
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: Attempt 1
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: Attempt 2
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: >>> Resource [id=1100, parent=SessionConfig [id=1096, configName=Sanity450LyncContactPictureConfig.tcl, modified=1545995407645, resources=6], line=3]
Hibernate: insert into session_config_resource (line, parent_id, id) values (?, ?, ?)
Hibernate: delete from session_config_resource where id=?
Hibernate: select count(*) as col_0_0_ from session_config_resource resource0_ where resource0_.id=?
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: exist? true
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: Attempt 1
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: Attempt 2
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: >>> Resource [id=1101, parent=SessionConfig [id=1096, configName=Sanity450LyncContactPictureConfig.tcl, modified=1545995407645, resources=6], line=4]
Hibernate: insert into session_config_resource (line, parent_id, id) values (?, ?, ?)
Hibernate: delete from session_config_resource where id=?
Hibernate: select count(*) as col_0_0_ from session_config_resource resource0_ where resource0_.id=?
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: exist? true
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: Attempt 1
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: Attempt 2
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: >>> Resource [id=1102, parent=SessionConfig [id=1096, configName=Sanity450LyncContactPictureConfig.tcl, modified=1545995407645, resources=6], line=5]
Hibernate: insert into session_config_resource (line, parent_id, id) values (?, ?, ?)
Hibernate: delete from session_config_resource where id=?
Hibernate: select count(*) as col_0_0_ from session_config_resource resource0_ where resource0_.id=?
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: exist? true
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: Attempt 1
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: Attempt 2
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: Attempt 3
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
2019-04-12 14:35:36 INFO  [scheduling-1] ResourceService.cleanResourcesForParent: flush
Hibernate: insert into session_config_resource (line, parent_id, id) values (?, ?, ?)
Hibernate: insert into session_config_resource (line, parent_id, id) values (?, ?, ?)
Hibernate: delete from session_config_resource where id=?
Hibernate: delete from session_config_resource where id=?
2019-04-12 14:35:36 INFO  [scheduling-1] SessionConfigServiceImpl.cacheSessionConfigData: Done

1 个答案:

答案 0 :(得分:0)

罪魁祸首(相信我误解了旗帜的用途)是“移除孤儿”选项,该选项从父项中标记出来:

 @OneToMany(mappedBy = "parent", orphanRemoval = true)
   @Cascade(values = {CascadeType.PERSIST, CascadeType.REMOVE});
   private List<Child> children = new LinkedList<Child>();

允许:

parent.getChildren().clear(); 
parentDao.saveAndFlush(parent);

最终结束这个问题。