diff --git a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java index 23a369e95..9dc650804 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/NetworkModificationRepository.java @@ -32,21 +32,21 @@ public class NetworkModificationRepository { private final ModificationRepository modificationRepository; - private final EquipmentModificationRepositories equipmentModificationRepositories; + private final TabularModificationRepository tabularModificationRepository; private static final String MODIFICATION_NOT_FOUND_MESSAGE = "Modification (%s) not found"; - public NetworkModificationRepository(ModificationGroupRepository modificationGroupRepository, ModificationRepository modificationRepository, EquipmentModificationRepositories equipmentModificationRepositories) { + public NetworkModificationRepository(ModificationGroupRepository modificationGroupRepository, ModificationRepository modificationRepository, TabularModificationRepository tabularModificationRepository) { this.modificationGroupRepository = modificationGroupRepository; this.modificationRepository = modificationRepository; - this.equipmentModificationRepositories = equipmentModificationRepositories; + this.tabularModificationRepository = tabularModificationRepository; } @Transactional // To have the 2 delete in the same transaction (atomic) public void deleteAll() { modificationRepository.deleteAll(); modificationGroupRepository.deleteAll(); - equipmentModificationRepositories.deleteAll(); + tabularModificationRepository.deleteAll(); } @Transactional // To have all create in the same transaction (atomic) @@ -141,63 +141,45 @@ public List getModifications(UUID groupUuid, boolean onlyMeta } public List getModificationsMetadata(UUID groupUuid, boolean onlyStashed) { - Stream modificationEntitySteam = modificationRepository + Stream modificationEntities = modificationRepository .findAllBaseByGroupId(getModificationGroup(groupUuid).getId()) .stream(); if (onlyStashed) { - return modificationEntitySteam.filter(m -> m.getStashed()) + return modificationEntities.filter(ModificationEntity::getStashed) .map(this::getModificationInfos) .collect(Collectors.toList()); } else { - return modificationEntitySteam + return modificationEntities .map(this::getModificationInfos) .collect(Collectors.toList()); } } - public TabularModificationEntity loadTabularModificationSubEntities(TabularModificationEntity tabularModificationEntity) { - switch (tabularModificationEntity.getModificationType()) { - case GENERATOR_MODIFICATION: - equipmentModificationRepositories.getGeneratorModificationRepository().findAllWithReactiveCapabilityCurvePointsByIdIn(tabularModificationEntity.getModifications().stream().map(ModificationEntity::getId).toList()); - break; - default: - break; - } - return tabularModificationEntity; - } - - public ModificationInfos getModificationInfos(ModificationEntity modificationEntity) { - if (modificationEntity instanceof TabularModificationEntity tabularModificationEntity) { - return loadTabularModificationSubEntities(tabularModificationEntity).toModificationInfos(); - } - return modificationEntity.toModificationInfos(); - } - public List getModificationsInfos(List groupUuids, boolean onlyStashed) { - Stream modificationEntity = groupUuids.stream().flatMap(this::getModificationEntityStream); + Stream modificationEntities = groupUuids.stream().flatMap(this::getModificationEntityStream); if (onlyStashed) { - return modificationEntity.filter(m -> m.getStashed() == onlyStashed) + return modificationEntities.filter(m -> m.getStashed() == onlyStashed) .map(this::getModificationInfos) .collect(Collectors.toList()); } else { - return modificationEntity.map(this::getModificationInfos) + return modificationEntities.map(this::getModificationInfos) .collect(Collectors.toList()); } } @Transactional(readOnly = true) public ModificationInfos getModificationInfo(UUID modificationUuid) { - Optional optionalModificationEntity = modificationRepository.findById(modificationUuid); - if (!optionalModificationEntity.isPresent()) { - throw new NetworkModificationException(MODIFICATION_NOT_FOUND, modificationUuid.toString()); - } - ModificationEntity modificationEntity = optionalModificationEntity.get(); + return modificationRepository.findById(modificationUuid) + .map(this::getModificationInfos) + .orElseThrow(() -> new NetworkModificationException(MODIFICATION_NOT_FOUND, modificationUuid.toString())); + } + + private ModificationInfos getModificationInfos(ModificationEntity modificationEntity) { if (modificationEntity instanceof TabularModificationEntity tabularModificationEntity) { - List ids = modificationRepository.findSubModificationsIds(modificationUuid); - tabularModificationEntity.setModifications(equipmentModificationRepositories.findSubEntities(tabularModificationEntity.getModificationType(), ids)); - return getModificationInfos(tabularModificationEntity); + tabularModificationRepository.fillSubEntities(tabularModificationEntity); + return tabularModificationEntity.toModificationInfos(); } - return getModificationInfos(modificationEntity); + return modificationEntity.toModificationInfos(); } @Transactional // To have the 2 delete in the same transaction (atomic) diff --git a/src/main/java/org/gridsuite/modification/server/repositories/EquipmentModificationRepositories.java b/src/main/java/org/gridsuite/modification/server/repositories/TabularModificationRepository.java similarity index 65% rename from src/main/java/org/gridsuite/modification/server/repositories/EquipmentModificationRepositories.java rename to src/main/java/org/gridsuite/modification/server/repositories/TabularModificationRepository.java index f6d068ff9..6a6eae9a8 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/EquipmentModificationRepositories.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/TabularModificationRepository.java @@ -2,17 +2,18 @@ import org.gridsuite.modification.server.ModificationType; import org.gridsuite.modification.server.entities.ModificationEntity; +import org.gridsuite.modification.server.entities.TabularModificationEntity; import org.gridsuite.modification.server.repositories.equipmentmodification.*; -import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; import java.util.List; import java.util.UUID; @Repository -public class EquipmentModificationRepositories { +public class TabularModificationRepository { + + private final ModificationRepository modificationRepository; private final BatteryModificationRepository batteryModificationRepository; @@ -30,16 +31,17 @@ public class EquipmentModificationRepositories { private final VoltageLevelModificationRepository voltageLevelModificationRepository; - public EquipmentModificationRepositories( - BatteryModificationRepository batteryModificationRepository, - GeneratorModificationRepository generatorModificationRepository, - LineModificationRepository lineModificationRepository, - LoadModificationRepository loadModificationRepository, - ShuntCompensatorModificationRepository shuntCompensatorModificationRepository, - SubstationModificationRepository substationModificationRepository, - TwoWindingsTransformerModificationRepository twoWindingsTransformerModificationRepository, - VoltageLevelModificationRepository voltageLevelModificationRepository + public TabularModificationRepository( + ModificationRepository modificationRepository, BatteryModificationRepository batteryModificationRepository, + GeneratorModificationRepository generatorModificationRepository, + LineModificationRepository lineModificationRepository, + LoadModificationRepository loadModificationRepository, + ShuntCompensatorModificationRepository shuntCompensatorModificationRepository, + SubstationModificationRepository substationModificationRepository, + TwoWindingsTransformerModificationRepository twoWindingsTransformerModificationRepository, + VoltageLevelModificationRepository voltageLevelModificationRepository ) { + this.modificationRepository = modificationRepository; this.batteryModificationRepository = batteryModificationRepository; this.generatorModificationRepository = generatorModificationRepository; this.lineModificationRepository = lineModificationRepository; @@ -62,20 +64,16 @@ public void deleteAll() { voltageLevelModificationRepository.deleteAll(); } - public GeneratorModificationRepository getGeneratorModificationRepository() { - return generatorModificationRepository; - } - - public List findSubEntities(ModificationType modificationType, List ids) { - List subEntities = new ArrayList<>(); - switch (modificationType) { - case GENERATOR_MODIFICATION -> subEntities.addAll(generatorModificationRepository.findAllWithReactiveCapabilityCurvePointsByIdIn(ids)); - default -> subEntities.addAll(getRepositoryByModificationType(modificationType).findAllById(ids)); - } - return subEntities; + public void fillSubEntities(TabularModificationEntity tabularModificationEntity) { + List ids = modificationRepository.findSubModificationsIds(tabularModificationEntity.getId()); + List modifications = getRepositoryByModificationType(tabularModificationEntity.getModificationType()).findAllEagerlyByIdIn(ids) + .stream() + .map(m -> (ModificationEntity) m) + .toList(); + tabularModificationEntity.setModifications(modifications); } - public JpaRepository getRepositoryByModificationType(ModificationType modificationType) { + private EagerNetworkModificationRepository getRepositoryByModificationType(ModificationType modificationType) { switch (modificationType) { case BATTERY_MODIFICATION -> { return batteryModificationRepository; @@ -101,9 +99,7 @@ public JpaRepository getRepositoryByModifica case VOLTAGE_LEVEL_MODIFICATION -> { return voltageLevelModificationRepository; } - default -> { - return null; - } + default -> throw new TabularModificationRepositoryException("Type " + modificationType + " should not be present in tabular modifications."); } } } diff --git a/src/main/java/org/gridsuite/modification/server/repositories/TabularModificationRepositoryException.java b/src/main/java/org/gridsuite/modification/server/repositories/TabularModificationRepositoryException.java new file mode 100644 index 000000000..02d0b0ab6 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/repositories/TabularModificationRepositoryException.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.gridsuite.modification.server.repositories; + +/** + * @author Joris Mancini + */ +public class TabularModificationRepositoryException extends RuntimeException { + + public TabularModificationRepositoryException(String message) { + super(message); + } +} diff --git a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/BatteryModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/BatteryModificationRepository.java index ccbf9c0d6..8d4814dec 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/BatteryModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/BatteryModificationRepository.java @@ -7,15 +7,20 @@ package org.gridsuite.modification.server.repositories.equipmentmodification; import org.gridsuite.modification.server.entities.equipment.modification.BatteryModificationEntity; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.UUID; /** * @author Etienne Homer */ @Repository -public interface BatteryModificationRepository extends JpaRepository { +public interface BatteryModificationRepository extends JpaRepository, EagerNetworkModificationRepository { + @Override + @EntityGraph(attributePaths = "properties", type = EntityGraph.EntityGraphType.LOAD) + List findAllEagerlyByIdIn(List ids); } diff --git a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/EagerNetworkModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/EagerNetworkModificationRepository.java new file mode 100644 index 000000000..8efa18d65 --- /dev/null +++ b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/EagerNetworkModificationRepository.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.gridsuite.modification.server.repositories.equipmentmodification; + +import org.gridsuite.modification.server.entities.ModificationEntity; + +import java.util.List; +import java.util.UUID; + +/** + * @author Joris Mancini + */ +public interface EagerNetworkModificationRepository { + + List findAllEagerlyByIdIn(List ids); +} diff --git a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/GeneratorModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/GeneratorModificationRepository.java index a72f70c55..5a96873d7 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/GeneratorModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/GeneratorModificationRepository.java @@ -18,8 +18,9 @@ * @author Etienne Homer */ @Repository -public interface GeneratorModificationRepository extends JpaRepository { +public interface GeneratorModificationRepository extends JpaRepository, EagerNetworkModificationRepository { - @EntityGraph(attributePaths = {"reactiveCapabilityCurvePoints"}, type = EntityGraph.EntityGraphType.LOAD) - List findAllWithReactiveCapabilityCurvePointsByIdIn(List ids); + @Override + @EntityGraph(attributePaths = {"reactiveCapabilityCurvePoints", "properties"}, type = EntityGraph.EntityGraphType.LOAD) + List findAllEagerlyByIdIn(List ids); } diff --git a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/LineModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/LineModificationRepository.java index f73f5cabe..4ecb77ea6 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/LineModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/LineModificationRepository.java @@ -7,15 +7,20 @@ package org.gridsuite.modification.server.repositories.equipmentmodification; import org.gridsuite.modification.server.entities.equipment.modification.LineModificationEntity; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.UUID; /** * @author Etienne Homer */ @Repository -public interface LineModificationRepository extends JpaRepository { +public interface LineModificationRepository extends JpaRepository, EagerNetworkModificationRepository { + @Override + @EntityGraph(attributePaths = "properties", type = EntityGraph.EntityGraphType.LOAD) + List findAllEagerlyByIdIn(List ids); } diff --git a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/LoadModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/LoadModificationRepository.java index 2be3c3d89..f87a4c41b 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/LoadModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/LoadModificationRepository.java @@ -7,15 +7,20 @@ package org.gridsuite.modification.server.repositories.equipmentmodification; import org.gridsuite.modification.server.entities.equipment.modification.LoadModificationEntity; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.UUID; /** * @author Etienne Homer */ @Repository -public interface LoadModificationRepository extends JpaRepository { +public interface LoadModificationRepository extends JpaRepository, EagerNetworkModificationRepository { + @Override + @EntityGraph(attributePaths = "properties", type = EntityGraph.EntityGraphType.LOAD) + List findAllEagerlyByIdIn(List ids); } diff --git a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/ShuntCompensatorModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/ShuntCompensatorModificationRepository.java index e2cde9296..d31e32196 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/ShuntCompensatorModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/ShuntCompensatorModificationRepository.java @@ -7,14 +7,20 @@ package org.gridsuite.modification.server.repositories.equipmentmodification; import org.gridsuite.modification.server.entities.equipment.modification.ShuntCompensatorModificationEntity; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.UUID; /** * @author Etienne Homer */ @Repository -public interface ShuntCompensatorModificationRepository extends JpaRepository { +public interface ShuntCompensatorModificationRepository extends JpaRepository, EagerNetworkModificationRepository { + + @Override + @EntityGraph(attributePaths = "properties", type = EntityGraph.EntityGraphType.LOAD) + List findAllEagerlyByIdIn(List ids); } diff --git a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/SubstationModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/SubstationModificationRepository.java index f6294e366..1f8bc4332 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/SubstationModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/SubstationModificationRepository.java @@ -7,15 +7,20 @@ package org.gridsuite.modification.server.repositories.equipmentmodification; import org.gridsuite.modification.server.entities.equipment.modification.SubstationModificationEntity; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.UUID; /** * @author Etienne Homer */ @Repository -public interface SubstationModificationRepository extends JpaRepository { +public interface SubstationModificationRepository extends JpaRepository, EagerNetworkModificationRepository { + @Override + @EntityGraph(attributePaths = "properties", type = EntityGraph.EntityGraphType.LOAD) + List findAllEagerlyByIdIn(List ids); } diff --git a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/TwoWindingsTransformerModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/TwoWindingsTransformerModificationRepository.java index f3d58bb78..0bf030809 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/TwoWindingsTransformerModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/TwoWindingsTransformerModificationRepository.java @@ -7,15 +7,20 @@ package org.gridsuite.modification.server.repositories.equipmentmodification; import org.gridsuite.modification.server.entities.equipment.modification.TwoWindingsTransformerModificationEntity; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.UUID; /** * @author Etienne Homer */ @Repository -public interface TwoWindingsTransformerModificationRepository extends JpaRepository { +public interface TwoWindingsTransformerModificationRepository extends JpaRepository, EagerNetworkModificationRepository { + @Override + @EntityGraph(attributePaths = {"properties", "tapChangerSteps"}, type = EntityGraph.EntityGraphType.LOAD) + List findAllEagerlyByIdIn(List ids); } diff --git a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/VoltageLevelModificationRepository.java b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/VoltageLevelModificationRepository.java index eb8a31ccd..4cc34c949 100644 --- a/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/VoltageLevelModificationRepository.java +++ b/src/main/java/org/gridsuite/modification/server/repositories/equipmentmodification/VoltageLevelModificationRepository.java @@ -7,15 +7,20 @@ package org.gridsuite.modification.server.repositories.equipmentmodification; import org.gridsuite.modification.server.entities.equipment.modification.VoltageLevelModificationEntity; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.UUID; /** * @author Etienne Homer */ @Repository -public interface VoltageLevelModificationRepository extends JpaRepository { +public interface VoltageLevelModificationRepository extends JpaRepository, EagerNetworkModificationRepository { + @Override + @EntityGraph(attributePaths = "properties", type = EntityGraph.EntityGraphType.LOAD) + List findAllEagerlyByIdIn(List ids); } diff --git a/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java b/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java index a8995755d..e2316c750 100644 --- a/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/modification/server/service/NetworkModificationService.java @@ -225,7 +225,7 @@ public Optional moveModifications(UUID groupUuid, UUI List movedModifications = networkModificationRepository.moveModifications(groupUuid, originGroupUuid, modificationsToMove, before) .stream() .filter(m -> !m.getStashed()) - .map(networkModificationRepository::getModificationInfos) + .map(ModificationEntity::toModificationInfos) .collect(Collectors.toList()); PreloadingStrategy preloadingStrategy = movedModifications.stream() @@ -260,7 +260,7 @@ private Optional saveAndApplyModifications(UUID targe if (!modificationEntities.isEmpty()) { networkModificationRepository.saveModifications(targetGroupUuid, modificationEntities); - List modificationInfos = modificationEntities.stream().map(networkModificationRepository::getModificationInfos).collect(Collectors.toList()); + List modificationInfos = modificationEntities.stream().map(ModificationEntity::toModificationInfos).collect(Collectors.toList()); PreloadingStrategy preloadingStrategy = modificationInfos.stream() .map(ModificationInfos::getType) @@ -284,7 +284,7 @@ public Optional duplicateModifications(UUID targetGro UUID networkUuid, String variantId, ReportInfos reportInfos, List modificationsUuids) { List modificationsEntities = networkModificationRepository.getModificationsEntities(modificationsUuids); - List duplicatedModificationsEntities = modificationsEntities.stream().map(m -> networkModificationRepository.getModificationInfos(m).toEntity()).collect(Collectors.toList()); + List duplicatedModificationsEntities = modificationsEntities.stream().map(m -> m.toModificationInfos().toEntity()).collect(Collectors.toList()); return saveAndApplyModifications(targetGroupUuid, networkUuid, variantId, reportInfos, duplicatedModificationsEntities); } diff --git a/src/test/java/org/gridsuite/modification/server/modifications/tabularmodifications/TabularGeneratorModificationsTest.java b/src/test/java/org/gridsuite/modification/server/modifications/tabularmodifications/TabularGeneratorModificationsTest.java index 926beb7a2..c115d2488 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/tabularmodifications/TabularGeneratorModificationsTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/tabularmodifications/TabularGeneratorModificationsTest.java @@ -101,7 +101,7 @@ public void testCheckSqlRequestsCount() throws Exception { mockMvc.perform(get("/v1/network-modifications/{uuid}", modificationUuid)).andExpectAll( status().isOk(), content().contentType(MediaType.APPLICATION_JSON)) .andReturn(); - assertSelectCount(4); + assertSelectCount(3); modifications = List.of( GeneratorModificationInfos.builder().equipmentId("idGenerator").maxActivePower(new AttributeModification<>(300., OperationType.SET)).build(), @@ -119,7 +119,7 @@ public void testCheckSqlRequestsCount() throws Exception { status().isOk(), content().contentType(MediaType.APPLICATION_JSON)) .andReturn(); // We check that the request count is not dependent on the number of sub modifications of the tabular modification (the JPA N+1 problem is correctly solved) - assertSelectCount(4); + assertSelectCount(3); reset(); // We get the modifications of the group (so the 2 tabular modifications)