diff --git a/compute/src/main/java/org/zstack/compute/vm/VmCascadeExtension.java b/compute/src/main/java/org/zstack/compute/vm/VmCascadeExtension.java index 250421d2ed..87f2edf689 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmCascadeExtension.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmCascadeExtension.java @@ -293,9 +293,36 @@ public void run(List replies) { private void handleDeletionCleanup(CascadeAction action, Completion completion) { dbf.eoCleanup(VmInstanceVO.class); + cleanupOrphanTemplatedVmInstance(); completion.success(); } + private void cleanupOrphanTemplatedVmInstance() { + new SQLBatch() { + @Override + protected void scripts() { + sql("delete from TemplatedVmInstanceRefVO ref" + + " where ref.vmInstanceUuid not in (select vm.uuid from VmInstanceEO vm)").execute(); + + List orphanUuids = sql("select t.uuid from TemplatedVmInstanceVO t" + + " where t.uuid not in (select vm.uuid from VmInstanceEO vm)", String.class).list(); + if (orphanUuids.isEmpty()) { + return; + } + + sql(TemplatedVmInstanceRefVO.class) + .in(TemplatedVmInstanceRefVO_.templatedVmInstanceUuid, orphanUuids) + .hardDelete(); + sql(TemplatedVmInstanceCacheVO.class) + .in(TemplatedVmInstanceCacheVO_.templatedVmInstanceUuid, orphanUuids) + .hardDelete(); + sql(TemplatedVmInstanceVO.class) + .in(TemplatedVmInstanceVO_.uuid, orphanUuids) + .hardDelete(); + } + }.execute(); + } + protected List handleDeletionForIpRange(List vminvs, List iprs) { List msgs = new ArrayList<>(); List uuids = iprs.stream().map(IpRangeInventory::getUuid).collect(Collectors.toList()); diff --git a/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotCascadeExtension.java b/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotCascadeExtension.java index 8116f9bad0..1c7b651d91 100755 --- a/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotCascadeExtension.java +++ b/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotCascadeExtension.java @@ -75,11 +75,13 @@ private void handleDeletionCleanup(CascadeAction action, Completion completion) } else { dbf.eoCleanup(VolumeSnapshotVO.class); dbf.eoCleanup(VolumeSnapshotGroupVO.class); + dbf.eoCleanup(VolumeSnapshotTreeVO.class); } } catch (NullPointerException e) { logger.warn(e.getLocalizedMessage()); dbf.eoCleanup(VolumeSnapshotVO.class); dbf.eoCleanup(VolumeSnapshotGroupVO.class); + dbf.eoCleanup(VolumeSnapshotTreeVO.class); } finally { completion.success(); }