From 0fd710c7e3479b90c74a562fe852dd283afdf2c8 Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 7 Feb 2024 12:56:08 +0100 Subject: [PATCH] SEBSERV-414 fix migration and DB consistency check for Orientations --- .../examconfig/impl/AttributeMapping.java | 29 ++++++++++------- .../OrientationTableDuplicatesCheck.java | 32 ++++++++++++++----- .../config/application-dev-ws.properties | 2 ++ 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/AttributeMapping.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/AttributeMapping.java index 8fa85bad..9b6582e8 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/AttributeMapping.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/AttributeMapping.java @@ -8,14 +8,11 @@ package ch.ethz.seb.sebserver.gui.service.examconfig.impl; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; +import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.OrientationRecord; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,34 +51,41 @@ public class AttributeMapping { .stream() .collect(Collectors.toMap( o -> o.attributeId, - Function.identity()))); - + Function.identity(), + (first, second) -> { + log.warn("*** Found duplicate orientation, use {} instead of {}", second, first); + return second; + }))); this.attributeIdMapping = Utils.immutableMapOf(attributes .stream() .filter(attr -> this.orientationAttributeMapping.containsKey(attr.id)) .collect(Collectors.toMap( attr -> attr.id, - Function.identity()))); + Function.identity(), + (first, second) -> second))); this.attributeNameIdMapping = Utils.immutableMapOf(attributes .stream() .filter(attr -> this.orientationAttributeMapping.containsKey(attr.id)) .collect(Collectors.toMap( attr -> attr.name, - attr -> attr.id))); + attr -> attr.id, + (first, second) -> second))); this.orientationAttributeNameMapping = Utils.immutableMapOf(orientations .stream() .collect(Collectors.toMap( o -> this.attributeIdMapping.get(o.attributeId).name, - Function.identity()))); + Function.identity(), + (first, second) -> second))); this.childAttributeMapping = Utils.immutableMapOf(attributes .stream() .filter(attr -> this.orientationAttributeMapping.containsKey(attr.id)) .collect(Collectors.toMap( attr -> attr.id, - this::getChildAttributes))); + this::getChildAttributes, + (first, second) -> second))); this.attributeGroupMapping = Utils.immutableMapOf(orientations .stream() @@ -91,7 +95,8 @@ public class AttributeMapping { .stream() .collect(Collectors.toMap( Function.identity(), - this::getAttributesOfGroup))); + this::getAttributesOfGroup, + (first, second) -> second))); } public Collection getAttributes() { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/datalayer/checks/OrientationTableDuplicatesCheck.java b/src/main/java/ch/ethz/seb/sebserver/webservice/datalayer/checks/OrientationTableDuplicatesCheck.java index b5935d6d..d3d5224f 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/datalayer/checks/OrientationTableDuplicatesCheck.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/datalayer/checks/OrientationTableDuplicatesCheck.java @@ -8,9 +8,7 @@ package ch.ethz.seb.sebserver.webservice.datalayer.checks; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import org.mybatis.dynamic.sql.SqlBuilder; @@ -68,7 +66,8 @@ public class OrientationTableDuplicatesCheck implements DBIntegrityCheck { final List checkedToDelete = toDelete .stream() - .filter(this::doubleCheck) + .map(this::getOldestForDeletion) + .filter(Objects::nonNull) .collect(Collectors.toList()); if (checkedToDelete == null || checkedToDelete.isEmpty()) { @@ -88,21 +87,38 @@ public class OrientationTableDuplicatesCheck implements DBIntegrityCheck { }); } - private boolean doubleCheck(final Long id) { + private Long getOldestForDeletion(final Long id) { try { final OrientationRecord selectByPrimaryKey = this.orientationRecordMapper.selectByPrimaryKey(id); - final Long count = this.orientationRecordMapper.countByExample() + final List records = this.orientationRecordMapper.selectByExample() .where( OrientationRecordDynamicSqlSupport.configAttributeId, SqlBuilder.isEqualTo(selectByPrimaryKey.getConfigAttributeId())) .and( OrientationRecordDynamicSqlSupport.templateId, SqlBuilder.isEqualTo(selectByPrimaryKey.getTemplateId())) + .orderBy(OrientationRecordDynamicSqlSupport.id) .build() .execute(); - return count != null && count.longValue() > 1; + + // get latest entry of duplicates + if (records != null && records.size() > 1) { + Long result = null; + for (int i = 0; i < records.size(); i++) { + final OrientationRecord rec = records.get(i); + if (result == null) { + result = rec.getId(); + continue; + } + if (result > rec.getId()) { + result = rec.getId(); + } + } + return result; + } + return null; } catch (final Exception e) { - return false; + return null; } } diff --git a/src/main/resources/config/application-dev-ws.properties b/src/main/resources/config/application-dev-ws.properties index 274eb616..9f9e5f2b 100644 --- a/src/main/resources/config/application-dev-ws.properties +++ b/src/main/resources/config/application-dev-ws.properties @@ -23,6 +23,8 @@ sebserver.webservice.distributed.updateInterval=1000 sebserver.webservice.distributed.connectionUpdate=2000 sebserver.webservice.clean-db-on-startup=false +sebserver.init.database.integrity.try-fix=true + # webservice setup configuration sebserver.init.adminaccount.gen-on-init=false sebserver.webservice.light.setup=false