@Override @SuppressWarnings("unchecked") public void clearUnusedForService(ServiceEntity service) { // this will actuall remove all data entities that are associated with an // non-existing dataset or are neither the first or last value for the // dataset, independent of the service DetachedCriteria existingDatasetIds = DetachedCriteria.forClass(DatasetEntity.class) .setProjection(Projections.distinct(Projections .property(DatasetEntity.PROPERTY_PKID))); DetachedCriteria minTimeByDataset = DetachedCriteria.forClass(DataEntity.class) .setProjection(Projections.projectionList() .add(Projections.groupProperty(DataEntity.PROPERTY_SERIES_PKID)) .add(Projections.min(DataEntity.PROPERTY_RESULTTIME))); DetachedCriteria maxTimeByDataset = DetachedCriteria.forClass(DataEntity.class) .setProjection(Projections.projectionList() .add(Projections.groupProperty(DataEntity.PROPERTY_SERIES_PKID)) .add(Projections.max(DataEntity.PROPERTY_RESULTTIME))); Criterion notExistingDataset = Subqueries.propertyNotIn(DataEntity.PROPERTY_SERIES_PKID, existingDatasetIds); Criterion notFirstData = Subqueries.propertiesNotIn(new String[] { DataEntity.PROPERTY_SERIES_PKID, DataEntity.PROPERTY_RESULTTIME }, minTimeByDataset); Criterion notLatestData = Subqueries.propertiesNotIn(new String[] { DataEntity.PROPERTY_SERIES_PKID, DataEntity.PROPERTY_RESULTTIME }, maxTimeByDataset); session.createCriteria(getEntityClass()) .add(Restrictions.or(notExistingDataset, Restrictions.and(notFirstData, notLatestData))) .list() .forEach(session::delete); }