diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c2ddf73..79c62f90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.1.0 + +* Restructured root to improve performance with IDs in entities + # 1.0.10 * Optimistic locking with @Version now possible diff --git a/docs/antora.yml b/docs/antora.yml index fe1e95a1..f0e594e0 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -1,14 +1,14 @@ name: ROOT title: Spring-Data-Eclipse-Store version: master -display_version: '1.0.10' +display_version: '2.0.0' start_page: index.adoc nav: - modules/ROOT/nav.adoc asciidoc: attributes: product-name: 'Spring-Data-Eclipse-Store' - display-version: '1.0.10' - maven-version: '1.0.10' + display-version: '2.0.0' + maven-version: '2.0.0' page-editable: false page-out-of-support: false diff --git a/pom.xml b/pom.xml index e405b61f..c04c8e6b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ software.xdev spring-data-eclipse-store-root - 1.0.11-SNAPSHOT + 2.0.0-SNAPSHOT pom diff --git a/spring-data-eclipse-store-benchmark/pom.xml b/spring-data-eclipse-store-benchmark/pom.xml index 33d6683f..bc549fc2 100644 --- a/spring-data-eclipse-store-benchmark/pom.xml +++ b/spring-data-eclipse-store-benchmark/pom.xml @@ -5,11 +5,11 @@ software.xdev spring-data-eclipse-store-root - 1.0.11-SNAPSHOT + 2.0.0-SNAPSHOT spring-data-eclipse-store-benchmark - 1.0.11-SNAPSHOT + 2.0.0-SNAPSHOT jar 2023 diff --git a/spring-data-eclipse-store-demo/pom.xml b/spring-data-eclipse-store-demo/pom.xml index ef2a2612..8d9ffd2d 100644 --- a/spring-data-eclipse-store-demo/pom.xml +++ b/spring-data-eclipse-store-demo/pom.xml @@ -7,11 +7,11 @@ software.xdev spring-data-eclipse-store-root - 1.0.11-SNAPSHOT + 2.0.0-SNAPSHOT spring-data-eclipse-store-demo - 1.0.11-SNAPSHOT + 2.0.0-SNAPSHOT jar diff --git a/spring-data-eclipse-store-jpa/pom.xml b/spring-data-eclipse-store-jpa/pom.xml index 57974811..c9cc4e6d 100644 --- a/spring-data-eclipse-store-jpa/pom.xml +++ b/spring-data-eclipse-store-jpa/pom.xml @@ -7,11 +7,11 @@ software.xdev spring-data-eclipse-store-root - 1.0.11-SNAPSHOT + 2.0.0-SNAPSHOT spring-data-eclipse-store-jpa - 1.0.11-SNAPSHOT + 2.0.0-SNAPSHOT jar 2023 diff --git a/spring-data-eclipse-store/pom.xml b/spring-data-eclipse-store/pom.xml index 8de55834..af423612 100644 --- a/spring-data-eclipse-store/pom.xml +++ b/spring-data-eclipse-store/pom.xml @@ -6,7 +6,7 @@ software.xdev spring-data-eclipse-store - 1.0.11-SNAPSHOT + 2.0.0-SNAPSHOT jar spring-data-eclipse-store @@ -148,6 +148,22 @@ ${org.eclipse.serializer.version} + + software.xdev + micro-migration + 2.0.0 + + + storage-embedded + org.eclipse.store + + + storage-embedded-configuration + org.eclipse.store + + + + org.junit.jupiter junit-jupiter-engine diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/core/EntityListProvider.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/core/EntityListProvider.java index f7a8c5fe..6114fef8 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/core/EntityListProvider.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/core/EntityListProvider.java @@ -17,7 +17,7 @@ public interface EntityListProvider { - EntityProvider getEntityProvider(final Class clazz); + EntityProvider getEntityProvider(final Class clazz); long getEntityCount(final Class clazz); } diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/core/EntityProvider.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/core/EntityProvider.java index 7e60f0a7..8a8ff19f 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/core/EntityProvider.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/core/EntityProvider.java @@ -18,23 +18,27 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; +import software.xdev.spring.data.eclipse.store.repository.root.EntityData; -public class EntityProvider + +@SuppressWarnings("java:S119") +public class EntityProvider { - private final List> identitySets = new ArrayList<>(); + private final List> entityDataList = new ArrayList<>(); - public void addIdentitySet(final IdentitySet identitySet) + public void addEntityData(final EntityData entityData) { - this.identitySets.add(identitySet); + this.entityDataList.add(entityData); } public Stream stream() { - return this.identitySets.stream().flatMap(Set::stream); + return this.entityDataList.stream().map(EntityData::getEntities).flatMap(Set::stream); } public Collection toCollection() @@ -51,4 +55,13 @@ public long size() { return this.stream().count(); } + + public Optional findAnyEntityWithId(final ID id) + { + return (Optional)this.entityDataList + .stream() + .map(entityData -> entityData.getEntitiesById().get(id)) + .filter(e -> e != null) + .findAny(); + } } diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/exceptions/InvalidRootException.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/exceptions/InvalidRootException.java new file mode 100644 index 00000000..421f4bb0 --- /dev/null +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/exceptions/InvalidRootException.java @@ -0,0 +1,24 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package software.xdev.spring.data.eclipse.store.exceptions; + +public class InvalidRootException extends RuntimeException +{ + public InvalidRootException(final String message) + { + super(message); + } +} diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/importer/EclipseStoreDataImporter.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/importer/EclipseStoreDataImporter.java index 823df08b..ffc73864 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/importer/EclipseStoreDataImporter.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/importer/EclipseStoreDataImporter.java @@ -34,8 +34,8 @@ import software.xdev.spring.data.eclipse.store.repository.SupportedChecker; import software.xdev.spring.data.eclipse.store.repository.config.EclipseStoreClientConfiguration; import software.xdev.spring.data.eclipse.store.repository.support.SimpleEclipseStoreRepository; -import software.xdev.spring.data.eclipse.store.repository.support.copier.id.IdManager; import software.xdev.spring.data.eclipse.store.repository.support.copier.working.RecursiveWorkingCopier; +import software.xdev.spring.data.eclipse.store.repository.support.id.IdManager; import software.xdev.spring.data.eclipse.store.transactions.EclipseStoreTransactionManager; diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreMigrator.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreMigrator.java new file mode 100644 index 00000000..84b0533f --- /dev/null +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreMigrator.java @@ -0,0 +1,53 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package software.xdev.spring.data.eclipse.store.repository; + +import java.util.TreeSet; + +import org.eclipse.store.storage.embedded.types.EmbeddedStorageManager; + +import software.xdev.micromigration.eclipsestore.MigrationManager; +import software.xdev.micromigration.migrater.reflection.ReflectiveMigrater; +import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript; +import software.xdev.micromigration.version.MigrationVersion; +import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; +import software.xdev.spring.data.eclipse.store.repository.root.update.scripts.v2_0_0_InitalizeVersioning; + + +public final class EclipseStoreMigrator +{ + public static final Class FIRST_UPDATE_SCRIPT = v2_0_0_InitalizeVersioning.class; + + private EclipseStoreMigrator() + { + } + + public static void migrate(final VersionedRoot versionedRoot, final EmbeddedStorageManager storageManager) + { + final ReflectiveMigrater migrater = + new ReflectiveMigrater(FIRST_UPDATE_SCRIPT.getPackageName()); + new MigrationManager(versionedRoot, migrater, storageManager) + .migrate(versionedRoot); + } + + public static MigrationVersion getLatestVersion() + { + final ReflectiveMigrater migrater = + new ReflectiveMigrater(FIRST_UPDATE_SCRIPT.getPackageName()); + final TreeSet> sortedScripts = migrater.getSortedScripts(); + return sortedScripts.isEmpty() ? new MigrationVersion(0, 0, 0) : sortedScripts.last().getTargetVersion(); + } +} diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreStorage.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreStorage.java index bfd86018..c5b7c1f8 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreStorage.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreStorage.java @@ -18,7 +18,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -27,29 +26,33 @@ import org.eclipse.serializer.persistence.types.Storer; import org.eclipse.serializer.reference.ObjectSwizzling; import org.eclipse.store.storage.embedded.types.EmbeddedStorageFoundation; +import org.eclipse.store.storage.embedded.types.EmbeddedStorageManager; import org.eclipse.store.storage.types.StorageManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.xdev.spring.data.eclipse.store.core.EntityListProvider; import software.xdev.spring.data.eclipse.store.core.EntityProvider; -import software.xdev.spring.data.eclipse.store.core.IdentitySet; import software.xdev.spring.data.eclipse.store.exceptions.AlreadyRegisteredException; +import software.xdev.spring.data.eclipse.store.exceptions.InvalidRootException; import software.xdev.spring.data.eclipse.store.repository.config.EclipseStoreClientConfiguration; import software.xdev.spring.data.eclipse.store.repository.config.EclipseStoreStorageFoundationProvider; +import software.xdev.spring.data.eclipse.store.repository.root.EntityData; +import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; import software.xdev.spring.data.eclipse.store.repository.support.SimpleEclipseStoreRepository; import software.xdev.spring.data.eclipse.store.repository.support.concurrency.ReadWriteLock; import software.xdev.spring.data.eclipse.store.repository.support.concurrency.ReentrantJavaReadWriteLock; -import software.xdev.spring.data.eclipse.store.repository.support.copier.id.IdManager; -import software.xdev.spring.data.eclipse.store.repository.support.copier.id.IdManagerProvider; -import software.xdev.spring.data.eclipse.store.repository.support.copier.id.IdSetter; import software.xdev.spring.data.eclipse.store.repository.support.copier.version.EntityVersionIncrementer; import software.xdev.spring.data.eclipse.store.repository.support.copier.version.VersionManager; import software.xdev.spring.data.eclipse.store.repository.support.copier.version.VersionManagerProvider; +import software.xdev.spring.data.eclipse.store.repository.support.id.IdManager; +import software.xdev.spring.data.eclipse.store.repository.support.id.IdManagerProvider; +import software.xdev.spring.data.eclipse.store.repository.support.id.IdSetter; import software.xdev.spring.data.eclipse.store.repository.support.reposyncer.RepositorySynchronizer; import software.xdev.spring.data.eclipse.store.repository.support.reposyncer.SimpleRepositorySynchronizer; +@SuppressWarnings("java:S119") public class EclipseStoreStorage implements EntityListProvider, IdManagerProvider, VersionManagerProvider, PersistableChecker, ObjectSwizzling { @@ -68,8 +71,8 @@ public class EclipseStoreStorage private final EclipseStoreStorageFoundationProvider foundationProvider; private EntitySetCollector entitySetCollector; private PersistableChecker persistenceChecker; - private StorageManager storageManager; - private Root root; + private EmbeddedStorageManager storageManager; + private VersionedRoot root; private final WorkingCopyRegistry registry = new WorkingCopyRegistry(); private final ReadWriteLock readWriteLock = new ReentrantJavaReadWriteLock(); @@ -95,24 +98,55 @@ private synchronized void ensureEntitiesInRoot() { if(this.storageManager == null) { - LOG.info("Starting storage..."); - this.root = new Root(); final EmbeddedStorageFoundation embeddedStorageFoundation = - this.foundationProvider.createEmbeddedStorageFoundation(); - embeddedStorageFoundation.registerTypeHandler(BinaryHandlerImmutableCollectionsSet12.New()); - embeddedStorageFoundation.registerTypeHandler(BinaryHandlerImmutableCollectionsList12.New()); - this.storageManager = embeddedStorageFoundation.start(this.root); + this.startStorageManager(); this.persistenceChecker = new RelayedPersistenceChecker(embeddedStorageFoundation); this.initRoot(); - final Integer entitySum = - this.root.getEntityLists().values().stream().map(IdentitySet::size).reduce(0, Integer::sum); LOG.info( "Storage started with {} entity lists and {} entities.", - this.root.getEntityLists().size(), - entitySum); + this.root.getCurrentRootData().getEntityTypesCount(), + this.root.getCurrentRootData().getEntityCount() + ); + EclipseStoreMigrator.migrate(this.root, this.storageManager); } } + private EmbeddedStorageFoundation startStorageManager() + { + LOG.info("Starting storage..."); + final EmbeddedStorageFoundation embeddedStorageFoundation = + this.foundationProvider.createEmbeddedStorageFoundation(); + embeddedStorageFoundation.registerTypeHandler(BinaryHandlerImmutableCollectionsSet12.New()); + embeddedStorageFoundation.registerTypeHandler(BinaryHandlerImmutableCollectionsList12.New()); + final EmbeddedStorageManager embeddedStorageManager = embeddedStorageFoundation.start(); + if(embeddedStorageManager.root() != null) + { + if(embeddedStorageManager.root() instanceof final Root oldRoot) + { + embeddedStorageManager.setRoot(new VersionedRoot(oldRoot)); + embeddedStorageManager.storeRoot(); + } + else if(!(embeddedStorageManager.root() instanceof VersionedRoot)) + { + throw new InvalidRootException( + "Root object of type %s is invalid." + .formatted(embeddedStorageManager.root() + .getClass() + .getName() + ) + ); + } + } + else + { + embeddedStorageManager.setRoot(new VersionedRoot()); + embeddedStorageManager.storeRoot(); + } + this.root = (VersionedRoot)embeddedStorageManager.root(); + this.storageManager = embeddedStorageManager; + return embeddedStorageFoundation; + } + public SimpleEclipseStoreRepository getRepository(final Class entityClass) { return (SimpleEclipseStoreRepository)this.entityClassToRepository.get(entityClass); @@ -125,28 +159,36 @@ private void initRoot() LOG.debug("Initializing entity lists..."); } this.repositorySynchronizer = - new SimpleRepositorySynchronizer(this.root); + new SimpleRepositorySynchronizer(this.root.getCurrentRootData()); boolean entityListMustGetStored = false; for(final Class entityClass : this.entityClassToRepository.keySet()) { - if(this.root.getEntityList(entityClass) == null) + if(this.root.getCurrentRootData().getEntityData(entityClass) == null) { - this.root.createNewEntityList(entityClass); + this.createNewEntityList(entityClass); entityListMustGetStored = true; } } if(entityListMustGetStored) { - this.storageManager.store(this.root.getEntityLists()); + this.storageManager.store(this.root.getCurrentRootData().getEntityListsToStore()); } this.entitySetCollector = - new EntitySetCollector(this.root::getEntityList, this.entityClassToRepository.keySet()); + new EntitySetCollector( + this.root.getCurrentRootData()::getEntityData, + this.entityClassToRepository.keySet()); if(LOG.isDebugEnabled()) { LOG.debug("Done initializing entity lists."); } } + private void createNewEntityList(final Class entityClass) + { + final IdManager idManager = this.ensureIdManager(entityClass); + this.root.getCurrentRootData().createNewEntityList(entityClass, idManager::getId); + } + public synchronized void registerEntity( final Class classToRegister, final SimpleEclipseStoreRepository repository) @@ -165,16 +207,16 @@ public synchronized void registerEntity( } } - private IdentitySet getEntityList(final Class clazz) + private EntityData getEntityData(final Class clazz) { this.ensureEntitiesInRoot(); return this.readWriteLock.read( - () -> this.root.getEntityList(clazz) + () -> this.root.getCurrentRootData().getEntityData(clazz) ); } @Override - public EntityProvider getEntityProvider(final Class clazz) + public EntityProvider getEntityProvider(final Class clazz) { this.ensureEntitiesInRoot(); return this.entitySetCollector.getRelatedIdentitySets(clazz); @@ -188,8 +230,8 @@ public long getEntityCount(final Class clazz) return this.readWriteLock.read( () -> { - final IdentitySet entityList = this.root.getEntityList(clazz); - return entityList == null ? 0 : entityList.size(); + final EntityData entityData = this.root.getCurrentRootData().getEntityData(clazz); + return entityData == null ? 0 : entityData.getEntityCount(); } ); } @@ -224,35 +266,32 @@ public void store( /** * Also collects the object-list to store, if necessary. */ - private Collection collectRootEntitiesToStore(final Class clazz, final Iterable entitiesToStore) + private Collection collectRootEntitiesToStore( + final Class clazz, + final Iterable entitiesToStore) { - final IdentitySet identitySet = this.getEntityList(clazz); + final EntityData entityData = this.getEntityData(clazz); final Collection objectsToStore = new ArrayList<>(); for(final T entityToStore : entitiesToStore) { - if(!identitySet.contains(entityToStore)) - { - identitySet.add(entityToStore); - objectsToStore.add(identitySet.getInternalMap()); - } + objectsToStore.addAll(entityData.ensureEntityAndReturnObjectsToStore(entityToStore)); objectsToStore.add(entityToStore); // Add the separate lists of entities to store. this.repositorySynchronizer.syncAndReturnChangedObjectLists(entityToStore).forEach( - changedEntityList -> objectsToStore.add(changedEntityList.getInternalMap()) + changedEntityList -> objectsToStore.addAll(changedEntityList.getObjectsToStore()) ); } return objectsToStore; } - public void delete(final Class clazz, final T objectToRemove) + public void delete(final Class clazz, final T entityToRemove) { this.ensureEntitiesInRoot(); this.readWriteLock.write( () -> { - final IdentitySet entityList = this.getEntityList(clazz); - entityList.remove(objectToRemove); - this.storageManager.store(entityList.getInternalMap()); + final EntityData entityData = this.getEntityData(clazz); + this.storageManager.storeAll(entityData.removeEntityAndReturnObjectsToStore(entityToRemove)); if(LOG.isDebugEnabled()) { LOG.debug("Deleted single entity of class {}.", clazz.getSimpleName()); @@ -261,17 +300,15 @@ public void delete(final Class clazz, final T objectToRemove) ); } - public void deleteAll(final Class clazz) + public void deleteAll(final Class clazz) { this.ensureEntitiesInRoot(); this.readWriteLock.write( () -> { - final IdentitySet entities = this.getEntityList(clazz); - final int oldSize = entities.size(); - final List entitiesToRemove = entities.stream().toList(); - entities.removeAll(entitiesToRemove); - this.storageManager.store(entities.getInternalMap()); + final EntityData entityData = this.getEntityData(clazz); + final long oldSize = entityData.getEntityCount(); + this.storageManager.storeAll(entityData.removeAllEntitiesAndReturnObjectsToStore()); if(LOG.isDebugEnabled()) { LOG.debug("Deleted {} entities of class {}.", oldSize, clazz.getSimpleName()); @@ -286,7 +323,7 @@ public void clearData() this.readWriteLock.write( () -> { - this.root = new Root(); + this.root = new VersionedRoot(); final StorageManager instanceOfstorageManager = this.getInstanceOfStorageManager(); this.initRoot(); @@ -370,7 +407,7 @@ public VersionManager ensureVersionManager(final Class possiblyVersion public Object getLastId(final Class entityClass) { - return this.readWriteLock.read(() -> this.root.getLastId(entityClass)); + return this.readWriteLock.read(() -> this.root.getCurrentRootData().getLastId(entityClass)); } public void setLastId(final Class entityClass, final Object lastId) @@ -378,8 +415,14 @@ public void setLastId(final Class entityClass, final Object lastId) this.readWriteLock.write( () -> { - this.root.setLastId(entityClass, lastId); - this.storageManager.store(this.root.getLastIds()); + final EntityData entityData = this.root.getCurrentRootData().getEntityData(entityClass); + if(entityData == null) + { + this.createNewEntityList(entityClass); + this.storageManager.store(this.root.getCurrentRootData().getEntityListsToStore()); + } + this.root.getCurrentRootData().setLastId(entityClass, lastId); + this.storageManager.store(this.root.getCurrentRootData().getObjectsToStoreAfterNewLastId(entityClass)); } ); } diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EntitySetCollector.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EntitySetCollector.java index 27cfbe04..4ca0f8d4 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EntitySetCollector.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EntitySetCollector.java @@ -24,23 +24,24 @@ import org.slf4j.LoggerFactory; import software.xdev.spring.data.eclipse.store.core.EntityProvider; -import software.xdev.spring.data.eclipse.store.core.IdentitySet; +import software.xdev.spring.data.eclipse.store.repository.root.EntityData; +@SuppressWarnings("java:S119") public class EntitySetCollector { private static final Logger LOG = LoggerFactory.getLogger(EntitySetCollector.class); - private final Map, EntityProvider> childClassToParentSets = new HashMap<>(); + private final Map, EntityProvider> childClassToParentSets = new HashMap<>(); - public EntitySetCollector( - final Function, IdentitySet> entityLists, + public EntitySetCollector( + final Function, EntityData> entityLists, final Set> entityClasses) { this.buildParentClassList(entityLists, entityClasses); } - private void buildParentClassList( - final Function, IdentitySet> entityLists, + private void buildParentClassList( + final Function, EntityData> entityLists, final Set> entityClasses ) { @@ -57,8 +58,8 @@ private void buildParentClassList( ); if(possibleChildEntry.isAssignableFrom(possibleParentEntry)) { - this.addIdentitySet( - (EntityProvider)this.childClassToParentSets.get(possibleChildEntry), + this.addEntityData( + (EntityProvider)this.childClassToParentSets.get(possibleChildEntry), entityLists, (Class)possibleParentEntry ); @@ -71,20 +72,20 @@ private void buildParentClassList( } } - private void addIdentitySet( - final EntityProvider entities, - final Function, IdentitySet> entityLists, + private void addEntityData( + final EntityProvider entities, + final Function, EntityData> entityLists, final Class possibleParentEntry ) { - entities.addIdentitySet(entityLists.apply(possibleParentEntry)); + entities.addEntityData(entityLists.apply(possibleParentEntry)); } /** * @return a list with all related IdentitySets (including its own). */ - public EntityProvider getRelatedIdentitySets(final Class clazz) + public EntityProvider getRelatedIdentitySets(final Class clazz) { - return (EntityProvider)this.childClassToParentSets.get(clazz); + return (EntityProvider)this.childClassToParentSets.get(clazz); } } diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/Root.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/Root.java index 0a4ad845..43d9991a 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/Root.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/Root.java @@ -22,8 +22,10 @@ /** - * This is the actually stored object. + * This is the root object for all versions <2.0.0 and is used for upgrading to the new root. + * @deprecated should not be initialised any more. Version for <2.0.0 */ +@Deprecated(forRemoval = false, since = "2.0.0") public class Root { private final Map> entityLists; @@ -64,6 +66,7 @@ public void setLastId(final Class entityClass, final Object lastId) { this.getLastIds().put(this.getEntityName(entityClass), lastId); } + public Map getLastIds() { return this.lastIds; diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreCrudRepository.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreCrudRepository.java index 325610c4..3dbb5f33 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreCrudRepository.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreCrudRepository.java @@ -19,6 +19,7 @@ import org.springframework.data.repository.NoRepositoryBean; +@SuppressWarnings("java:S119") @NoRepositoryBean public interface EclipseStoreCrudRepository extends CrudRepository { diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreCustomRepository.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreCustomRepository.java index 97c7b09e..c027ae0a 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreCustomRepository.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreCustomRepository.java @@ -19,6 +19,7 @@ import org.springframework.data.repository.Repository; +@SuppressWarnings("java:S119") @NoRepositoryBean public interface EclipseStoreCustomRepository extends Repository { diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreListCrudRepository.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreListCrudRepository.java index ac91ce71..7a8f86dc 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreListCrudRepository.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreListCrudRepository.java @@ -19,6 +19,7 @@ import org.springframework.data.repository.NoRepositoryBean; +@SuppressWarnings("java:S119") @NoRepositoryBean public interface EclipseStoreListCrudRepository extends ListCrudRepository { diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreListPagingAndSortingRepositoryRepository.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreListPagingAndSortingRepositoryRepository.java index 34a774fb..72be795d 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreListPagingAndSortingRepositoryRepository.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreListPagingAndSortingRepositoryRepository.java @@ -19,6 +19,7 @@ import org.springframework.data.repository.NoRepositoryBean; +@SuppressWarnings("java:S119") @NoRepositoryBean public interface EclipseStoreListPagingAndSortingRepositoryRepository extends ListPagingAndSortingRepository diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStorePagingAndSortingRepositoryRepository.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStorePagingAndSortingRepositoryRepository.java index 33e65618..a4c4b37c 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStorePagingAndSortingRepositoryRepository.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStorePagingAndSortingRepositoryRepository.java @@ -19,6 +19,7 @@ import org.springframework.data.repository.PagingAndSortingRepository; +@SuppressWarnings("java:S119") @NoRepositoryBean public interface EclipseStorePagingAndSortingRepositoryRepository extends PagingAndSortingRepository diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreQueryByExampleExecutor.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreQueryByExampleExecutor.java index c15f1ee6..743da1dc 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreQueryByExampleExecutor.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreQueryByExampleExecutor.java @@ -19,6 +19,7 @@ import org.springframework.data.repository.query.QueryByExampleExecutor; +@SuppressWarnings("java:S119") @NoRepositoryBean public interface EclipseStoreQueryByExampleExecutor extends QueryByExampleExecutor { diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreRepository.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreRepository.java index 7cde04a0..3fb889dd 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreRepository.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/interfaces/EclipseStoreRepository.java @@ -18,6 +18,7 @@ import org.springframework.data.repository.NoRepositoryBean; +@SuppressWarnings("java:S119") @NoRepositoryBean public interface EclipseStoreRepository extends diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/CountQueryExecutor.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/CountQueryExecutor.java index 6684bbb6..a99688c1 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/CountQueryExecutor.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/CountQueryExecutor.java @@ -46,7 +46,7 @@ public CountQueryExecutor(final Criteria criteria) * @return a list of the found/sorted/paged entities */ @Override - public Long execute(final Class clazz, @Nullable final EntityProvider entities, final Object[] values) + public Long execute(final Class clazz, @Nullable final EntityProvider entities, final Object[] values) { Objects.requireNonNull(entities); diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/ExistsQueryExecutor.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/ExistsQueryExecutor.java index 69a8348d..49b6d819 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/ExistsQueryExecutor.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/ExistsQueryExecutor.java @@ -51,7 +51,7 @@ public ExistsQueryExecutor(final Criteria criteria) @Override public Boolean execute( final Class clazz, - @Nullable final EntityProvider entities, + @Nullable final EntityProvider entities, @Nullable final Object[] values) { Objects.requireNonNull(clazz); diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/ListQueryExecutor.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/ListQueryExecutor.java index a2a788a5..a9be1d00 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/ListQueryExecutor.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/ListQueryExecutor.java @@ -53,7 +53,7 @@ public ListQueryExecutor(final WorkingCopier copier, final Criteria criter * @return a list of the found/sorted/paged entities */ @Override - public List execute(final Class clazz, @Nullable final EntityProvider entities, final Object[] values) + public List execute(final Class clazz, @Nullable final EntityProvider entities, final Object[] values) { Objects.requireNonNull(clazz); if(entities == null || entities.isEmpty()) diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/PageableQueryExecutor.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/PageableQueryExecutor.java index 5628cf73..7414db51 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/PageableQueryExecutor.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/PageableQueryExecutor.java @@ -52,7 +52,7 @@ public PageableQueryExecutor(final WorkingCopier copier, final Criteria cr * @return a page of the found/sorted/paged entities */ @Override - public Page execute(final Class clazz, @Nullable final EntityProvider entities, final Object[] values) + public Page execute(final Class clazz, @Nullable final EntityProvider entities, final Object[] values) { Objects.requireNonNull(clazz); diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/PageableSortableCollectionQuerier.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/PageableSortableCollectionQuerier.java index 7602077a..18d8bb89 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/PageableSortableCollectionQuerier.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/PageableSortableCollectionQuerier.java @@ -58,7 +58,7 @@ public PageableSortableCollectionQuerier( } protected List getEntities( - @Nonnull final EntityProvider entities, + @Nonnull final EntityProvider entities, @Nullable final Pageable pageable, @Nullable final Class clazz, @Nullable final Sort sort) @@ -106,7 +106,7 @@ private Stream pageEntityStream(final Pageable pageable, final Stre } protected List getEntities( - final EntityProvider entities, + final EntityProvider entities, final Pageable pageable, final Class clazz) { @@ -114,14 +114,14 @@ protected List getEntities( } protected List getEntities( - final EntityProvider entities, + final EntityProvider entities, final Class clazz, final Sort sort) { return this.getEntities(entities, null, clazz, sort); } - protected List getEntities(final EntityProvider entities, final Class clazz) + protected List getEntities(final EntityProvider entities, final Class clazz) { return this.getEntities(entities, null, clazz, null); } diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/QueryExecutor.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/QueryExecutor.java index f8e89c9d..27237612 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/QueryExecutor.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/QueryExecutor.java @@ -36,5 +36,5 @@ public interface QueryExecutor * @param values for the query. These are values that might be compared to entities. * @return entities/entity on which the conditions match. */ - Object execute(Class clazz, final EntityProvider entities, Object[] values); + Object execute(Class clazz, final EntityProvider entities, Object[] values); } diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/SingleOptionalQueryExecutor.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/SingleOptionalQueryExecutor.java index 0f0eb425..3116eb35 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/SingleOptionalQueryExecutor.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/SingleOptionalQueryExecutor.java @@ -57,7 +57,7 @@ public SingleOptionalQueryExecutor(final WorkingCopier copier, final Criteria @Override public Optional execute( final Class clazz, - @Nullable final EntityProvider entities, + @Nullable final EntityProvider entities, @Nullable final Object[] values) { Objects.requireNonNull(clazz); diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/SingleQueryExecutor.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/SingleQueryExecutor.java index 70cb3e0c..ef6e017f 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/SingleQueryExecutor.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/query/executors/SingleQueryExecutor.java @@ -48,7 +48,7 @@ public SingleQueryExecutor(final WorkingCopier copier, final Criteria crit @Override public T execute( @Nullable final Class clazz, - @Nullable final EntityProvider entities, + @Nullable final EntityProvider entities, @Nullable final Object[] values) { final Optional optionalResult = this.optionalQueryExecutor.execute(clazz, entities, values); diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/EntityData.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/EntityData.java new file mode 100644 index 00000000..eca8b7aa --- /dev/null +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/EntityData.java @@ -0,0 +1,106 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package software.xdev.spring.data.eclipse.store.repository.root; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.function.Function; + +import software.xdev.spring.data.eclipse.store.core.IdentitySet; + + +/** + * @param type of entity to store + * @param type of id of the entity to store. Can be {@link Void} if no ID is used. + */ +public class EntityData +{ + private final IdentitySet entities; + private ID lastId; + /** + * "Why do you keep the entites at two places? This seems like a waste of space." - Yes, it seems like it is + * duplicated information, but we need to be able to find an entity based on its identity as fast as possible + * ({@link #entities} and also find an entity based on its id {@link #entitiesById}. We could use the BiMaps + * provided by google and apache, but they implemented this also with two seperate lists so there is no benefit in + * using these. + */ + private final HashMap entitiesById; + + private final transient Function idGetter; + + public EntityData(final Function idGetter) + { + this.idGetter = idGetter; + this.entities = new IdentitySet<>(); + this.entitiesById = new HashMap<>(); + } + + public IdentitySet getEntities() + { + return this.entities; + } + + public ID getLastId() + { + return this.lastId; + } + + public HashMap getEntitiesById() + { + return this.entitiesById; + } + + public long getEntityCount() + { + return this.entities.size(); + } + + public void setLastId(final Object lastId) + { + this.lastId = (ID)lastId; + } + + public Collection ensureEntityAndReturnObjectsToStore(final T entityToStore) + { + if(!this.getEntities().contains(entityToStore)) + { + this.entities.add(entityToStore); + this.entitiesById.put(this.idGetter.apply(entityToStore), entityToStore); + return this.getObjectsToStore(); + } + return List.of(); + } + + public Collection getObjectsToStore() + { + return List.of(this.entities.getInternalMap(), this.entitiesById); + } + + public Collection removeEntityAndReturnObjectsToStore(final T entityToRemove) + { + this.entities.remove(entityToRemove); + this.entitiesById.remove(this.idGetter.apply(entityToRemove)); + return this.getObjectsToStore(); + } + + public Collection removeAllEntitiesAndReturnObjectsToStore() + { + this.entities.clear(); + this.entitiesById.clear(); + return this.getObjectsToStore(); + } +} diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/RootDataV2.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/RootDataV2.java new file mode 100644 index 00000000..ef853c1c --- /dev/null +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/RootDataV2.java @@ -0,0 +1,88 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package software.xdev.spring.data.eclipse.store.repository.root; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + + +/** + * This is the actually stored object. + */ +@SuppressWarnings("java:S119") +public class RootDataV2 +{ + private final Map> entityLists; + + public RootDataV2() + { + this.entityLists = new HashMap<>(); + } + + public Object getEntityListsToStore() + { + return this.entityLists; + } + + public long getEntityTypesCount() + { + return this.entityLists.size(); + } + + public long getEntityCount() + { + return this.entityLists.values().stream().map(EntityData::getEntityCount).reduce(0L, Long::sum); + } + + public EntityData getEntityData(final Class entityClass) + { + return this.getEntityData(this.getEntityName(entityClass)); + } + + public EntityData getEntityData(final String entityClassName) + { + return (EntityData)this.entityLists.get(entityClassName); + } + + public void createNewEntityList( + final Class entityClass, + final Function idGetter) + { + this.entityLists.put(this.getEntityName(entityClass), new EntityData<>(idGetter)); + } + + private String getEntityName(final Class classToRegister) + { + return classToRegister.getName(); + } + + public Object getLastId(final Class entityClass) + { + final EntityData entityData = this.entityLists.get(this.getEntityName(entityClass)); + return entityData == null ? null : entityData.getLastId(); + } + + public void setLastId(final Class entityClass, final Object lastId) + { + this.entityLists.get(this.getEntityName(entityClass)).setLastId(lastId); + } + + public Object getObjectsToStoreAfterNewLastId(final Class entityClass) + { + return this.entityLists.get(this.getEntityName(entityClass)); + } +} diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/VersionedRoot.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/VersionedRoot.java new file mode 100644 index 00000000..19a70e75 --- /dev/null +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/VersionedRoot.java @@ -0,0 +1,85 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package software.xdev.spring.data.eclipse.store.repository.root; + +import software.xdev.micromigration.version.MigrationVersion; +import software.xdev.micromigration.version.Versioned; +import software.xdev.spring.data.eclipse.store.repository.EclipseStoreMigrator; +import software.xdev.spring.data.eclipse.store.repository.Root; + + +public class VersionedRoot implements Versioned +{ + private MigrationVersion version; + + private Root rootDataV1; + + private final RootDataV2 rootDataV2; + + public VersionedRoot() + { + this(null); + } + + /** + * @param rootDataV1 is only filled if this is a old version <2.0.0 and needs upgrading + */ + public VersionedRoot(final Root rootDataV1) + { + this.rootDataV1 = rootDataV1; + this.rootDataV2 = new RootDataV2(); + if(rootDataV1 != null) + { + this.version = new MigrationVersion(0, 0, 0); + } + else + { + this.version = EclipseStoreMigrator.getLatestVersion(); + } + } + + public Root getRootDataV1() + { + return this.rootDataV1; + } + + public RootDataV2 getRootDataV2() + { + return this.rootDataV2; + } + + public void clearOldRootData() + { + this.rootDataV1 = null; + } + + public RootDataV2 getCurrentRootData() + { + return this.rootDataV2; + } + + @Override + public void setVersion(final MigrationVersion migrationVersion) + { + this.version = migrationVersion; + } + + @Override + public MigrationVersion getVersion() + { + return this.version; + } +} diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/LoggingUpdateScript.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/LoggingUpdateScript.java new file mode 100644 index 00000000..934ddab1 --- /dev/null +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/LoggingUpdateScript.java @@ -0,0 +1,41 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package software.xdev.spring.data.eclipse.store.repository.root.update.scripts; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager; +import software.xdev.micromigration.scripts.Context; +import software.xdev.micromigration.scripts.ReflectiveVersionMigrationScript; +import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; + + +public abstract class LoggingUpdateScript + extends ReflectiveVersionMigrationScript +{ + private static final Logger LOG = LoggerFactory.getLogger(LoggingUpdateScript.class); + + @Override + public void migrate(final Context context) + { + LOG.info("Applying update {}...", this.getClass().getSimpleName()); + this.loggedMigrate(context); + LOG.info("Applied update {}.", this.getClass().getSimpleName()); + } + + public abstract void loggedMigrate(final Context context); +} diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/v2_0_0_InitalizeVersioning.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/v2_0_0_InitalizeVersioning.java new file mode 100644 index 00000000..ec4d971c --- /dev/null +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/v2_0_0_InitalizeVersioning.java @@ -0,0 +1,61 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package software.xdev.spring.data.eclipse.store.repository.root.update.scripts; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager; +import software.xdev.micromigration.scripts.Context; +import software.xdev.spring.data.eclipse.store.repository.root.EntityData; +import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; + + +@SuppressWarnings("checkstyle:TypeName") +public class v2_0_0_InitalizeVersioning extends LoggingUpdateScript +{ + private static final Logger LOG = LoggerFactory.getLogger(v2_0_0_InitalizeVersioning.class); + + @Override + public void loggedMigrate(final Context context) + { + final VersionedRoot versionedRoot = context.getMigratingObject(); + versionedRoot.getRootDataV1().getEntityLists().forEach( + (entityName, entities) -> + { + final EntityData entityData = versionedRoot.getRootDataV2().getEntityData(entityName); + if(entityData == null) + { + LOG.warn("Dropping entities {} because there is no repository in the new root.", entityName); + } + entities.forEach(entity -> entityData.ensureEntityAndReturnObjectsToStore(entity)); + context.getStorageManager().getNativeStorageManager().storeAll(entityData.getObjectsToStore()); + LOG.info("Migrated entities {}.", entityName); + } + ); + versionedRoot.getRootDataV1().getLastIds().forEach( + (entityName, lastId) -> + { + final EntityData entityData = versionedRoot.getRootDataV2().getEntityData(entityName); + entityData.setLastId(lastId); + context.getStorageManager().store(entityData); + LOG.info("Migrated last id of entities {}.", entityName); + } + ); + versionedRoot.clearOldRootData(); + context.getStorageManager().store(versionedRoot); + } +} diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/EclipseStoreRepositoryFactory.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/EclipseStoreRepositoryFactory.java index 9af01738..864c347d 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/EclipseStoreRepositoryFactory.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/EclipseStoreRepositoryFactory.java @@ -41,6 +41,7 @@ /** * Creates the correct repository instance for repository-interfaces. */ +@SuppressWarnings("java:S119") public class EclipseStoreRepositoryFactory extends RepositoryFactorySupport { private final EclipseStoreStorage storage; diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/EclipseStoreRepositoryFactoryBean.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/EclipseStoreRepositoryFactoryBean.java index 847bade3..e8a11842 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/EclipseStoreRepositoryFactoryBean.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/EclipseStoreRepositoryFactoryBean.java @@ -42,6 +42,7 @@ "software.xdev.spring.data.eclipse.store.transactions" }) @Component +@SuppressWarnings("java:S119") public class EclipseStoreRepositoryFactoryBean, S, ID extends Serializable> extends RepositoryFactoryBeanSupport { diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/SimpleEclipseStoreRepository.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/SimpleEclipseStoreRepository.java index 9997eb51..a8945976 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/SimpleEclipseStoreRepository.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/SimpleEclipseStoreRepository.java @@ -50,13 +50,14 @@ import software.xdev.spring.data.eclipse.store.repository.query.executors.ListQueryExecutor; import software.xdev.spring.data.eclipse.store.repository.query.executors.PageableQueryExecutor; import software.xdev.spring.data.eclipse.store.repository.query.executors.SingleOptionalQueryExecutor; -import software.xdev.spring.data.eclipse.store.repository.support.copier.id.IdManager; import software.xdev.spring.data.eclipse.store.repository.support.copier.working.WorkingCopier; import software.xdev.spring.data.eclipse.store.repository.support.copier.working.WorkingCopierResult; +import software.xdev.spring.data.eclipse.store.repository.support.id.IdManager; import software.xdev.spring.data.eclipse.store.transactions.EclipseStoreTransaction; import software.xdev.spring.data.eclipse.store.transactions.EclipseStoreTransactionManager; +@SuppressWarnings("java:S119") public class SimpleEclipseStoreRepository implements EclipseStoreRepository, diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/version/incrementer/UUIDVersionIncrementer.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/version/incrementer/UUIDVersionIncrementer.java index febc75c0..6c12c0a8 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/version/incrementer/UUIDVersionIncrementer.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/version/incrementer/UUIDVersionIncrementer.java @@ -18,6 +18,7 @@ import java.util.UUID; +@SuppressWarnings("java:S119") public class UUIDVersionIncrementer implements VersionIncrementer { @Override diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/working/RecursiveWorkingCopier.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/working/RecursiveWorkingCopier.java index 3e991592..25ac94af 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/working/RecursiveWorkingCopier.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/working/RecursiveWorkingCopier.java @@ -41,13 +41,13 @@ import software.xdev.spring.data.eclipse.store.repository.access.modifier.FieldAccessModifier; import software.xdev.spring.data.eclipse.store.repository.lazy.SpringDataEclipseStoreLazy; import software.xdev.spring.data.eclipse.store.repository.support.copier.DataTypeUtil; -import software.xdev.spring.data.eclipse.store.repository.support.copier.id.IdManager; -import software.xdev.spring.data.eclipse.store.repository.support.copier.id.IdManagerProvider; import software.xdev.spring.data.eclipse.store.repository.support.copier.registering.RegisteringObjectCopier; import software.xdev.spring.data.eclipse.store.repository.support.copier.registering.RegisteringStorageToWorkingCopyCopier; import software.xdev.spring.data.eclipse.store.repository.support.copier.registering.RegisteringWorkingCopyToStorageCopier; import software.xdev.spring.data.eclipse.store.repository.support.copier.version.VersionManager; import software.xdev.spring.data.eclipse.store.repository.support.copier.version.VersionManagerProvider; +import software.xdev.spring.data.eclipse.store.repository.support.id.IdManager; +import software.xdev.spring.data.eclipse.store.repository.support.id.IdManagerProvider; /** diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/EntityGetterById.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/EntityGetterById.java similarity index 95% rename from spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/EntityGetterById.java rename to spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/EntityGetterById.java index 91e44a5c..05bfb2f8 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/EntityGetterById.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/EntityGetterById.java @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package software.xdev.spring.data.eclipse.store.repository.support.copier.id; +package software.xdev.spring.data.eclipse.store.repository.support.id; import java.util.Optional; +@SuppressWarnings("java:S119") public interface EntityGetterById { Optional findById(ID id); diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/IdGetter.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/IdGetter.java similarity index 92% rename from spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/IdGetter.java rename to spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/IdGetter.java index d10b5f06..9ed958ce 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/IdGetter.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/IdGetter.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package software.xdev.spring.data.eclipse.store.repository.support.copier.id; +package software.xdev.spring.data.eclipse.store.repository.support.id; public interface IdGetter { - ID getId(T objectToSetIdIn) throws Exception; + ID getId(T objectToSetIdIn); } diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/IdManager.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/IdManager.java similarity index 87% rename from spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/IdManager.java rename to spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/IdManager.java index 463729aa..41ef91ba 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/IdManager.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/IdManager.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package software.xdev.spring.data.eclipse.store.repository.support.copier.id; +package software.xdev.spring.data.eclipse.store.repository.support.id; import java.lang.reflect.Field; import java.util.Collection; @@ -31,6 +31,7 @@ import software.xdev.spring.data.eclipse.store.repository.support.AnnotatedFieldFinder; +@SuppressWarnings("java:S119") public class IdManager implements EntityGetterById, IdGetter { private final Class classWithId; @@ -65,33 +66,23 @@ public Field ensureIdField() public Optional findById(@Nonnull final ID id) { this.ensureIdField(); - return (Optional)this.storage.getReadWriteLock().read( + return this.storage.getReadWriteLock().read( () -> this.storage .getEntityProvider(this.classWithId) - .stream() - .filter(entity -> id.equals(this.getId(entity))) - .findAny() + .findAnyEntityWithId(id) ); } public List findAllById(@Nonnull final Iterable idsToFind) { this.ensureIdField(); - return (List)this.storage.getReadWriteLock().read( - () -> this.storage - .getEntityProvider(this.classWithId) - .stream() - .filter( - entity -> - { - final Object idOfEntity = this.getId(entity); - return StreamSupport - .stream(idsToFind.spliterator(), false) - .anyMatch(idToFind -> idToFind.equals(idOfEntity)); - } - ) - .toList() - ); + + return StreamSupport + .stream(idsToFind.spliterator(), false) + .map(this::findById) + .filter(e -> e.isPresent()) + .map(Optional::get) + .toList(); } public IdSetter getIdSetter() @@ -140,7 +131,7 @@ public void checkIds(final Collection entities) } final List ids = entities .stream() - .map(entity -> this.getId(entity)) + .map(this::getId) .toList(); if(!this.getIdSetter().isAutomaticSetter() && ids.contains(null)) diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/IdManagerProvider.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/IdManagerProvider.java similarity index 95% rename from spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/IdManagerProvider.java rename to spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/IdManagerProvider.java index 00137c71..8b975582 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/IdManagerProvider.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/IdManagerProvider.java @@ -13,8 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package software.xdev.spring.data.eclipse.store.repository.support.copier.id; +package software.xdev.spring.data.eclipse.store.repository.support.id; +@SuppressWarnings("java:S119") public interface IdManagerProvider { IdManager ensureIdManager(final Class domainClass); diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/IdSetter.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/IdSetter.java similarity index 98% rename from spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/IdSetter.java rename to spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/IdSetter.java index 5493f93f..030df5c4 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/IdSetter.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/IdSetter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package software.xdev.spring.data.eclipse.store.repository.support.copier.id; +package software.xdev.spring.data.eclipse.store.repository.support.id; import java.lang.reflect.Field; import java.util.Objects; @@ -24,7 +24,7 @@ import jakarta.persistence.GeneratedValue; import software.xdev.spring.data.eclipse.store.repository.support.AnnotatedFieldFinder; -import software.xdev.spring.data.eclipse.store.repository.support.copier.id.strategy.IdFinder; +import software.xdev.spring.data.eclipse.store.repository.support.id.strategy.IdFinder; /** diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/NotSettingIdSetter.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/NotSettingIdSetter.java similarity index 98% rename from spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/NotSettingIdSetter.java rename to spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/NotSettingIdSetter.java index 1ee781f2..9fd1ba41 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/NotSettingIdSetter.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/NotSettingIdSetter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package software.xdev.spring.data.eclipse.store.repository.support.copier.id; +package software.xdev.spring.data.eclipse.store.repository.support.id; public class NotSettingIdSetter implements IdSetter { diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/SimpleIdSetter.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/SimpleIdSetter.java similarity index 97% rename from spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/SimpleIdSetter.java rename to spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/SimpleIdSetter.java index 30aa830a..79cc31ae 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/SimpleIdSetter.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/SimpleIdSetter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package software.xdev.spring.data.eclipse.store.repository.support.copier.id; +package software.xdev.spring.data.eclipse.store.repository.support.id; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -22,9 +22,10 @@ import software.xdev.spring.data.eclipse.store.exceptions.FieldAccessReflectionException; import software.xdev.spring.data.eclipse.store.exceptions.IdFieldFinalException; import software.xdev.spring.data.eclipse.store.repository.access.modifier.FieldAccessModifier; -import software.xdev.spring.data.eclipse.store.repository.support.copier.id.strategy.IdFinder; +import software.xdev.spring.data.eclipse.store.repository.support.id.strategy.IdFinder; +@SuppressWarnings("java:S119") public class SimpleIdSetter implements IdSetter { private final IdFinder idFinder; diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/IdFinder.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/IdFinder.java similarity index 93% rename from spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/IdFinder.java rename to spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/IdFinder.java index 88391777..59dd6649 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/IdFinder.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/IdFinder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package software.xdev.spring.data.eclipse.store.repository.support.copier.id.strategy; +package software.xdev.spring.data.eclipse.store.repository.support.id.strategy; import java.lang.reflect.Field; import java.util.Objects; @@ -23,15 +23,16 @@ import jakarta.persistence.GenerationType; import software.xdev.spring.data.eclipse.store.exceptions.IdGeneratorNotSupportedException; -import software.xdev.spring.data.eclipse.store.repository.support.copier.id.strategy.auto.AutoIntegerIdFinder; -import software.xdev.spring.data.eclipse.store.repository.support.copier.id.strategy.auto.AutoLongIdFinder; -import software.xdev.spring.data.eclipse.store.repository.support.copier.id.strategy.auto.AutoStringIdFinder; +import software.xdev.spring.data.eclipse.store.repository.support.id.strategy.auto.AutoIntegerIdFinder; +import software.xdev.spring.data.eclipse.store.repository.support.id.strategy.auto.AutoLongIdFinder; +import software.xdev.spring.data.eclipse.store.repository.support.id.strategy.auto.AutoStringIdFinder; /** * A IdFinder must be unique in one storage for one entity-class. It creates Ids and therefore must know all * existing entities of one class. */ +@SuppressWarnings("java:S119") public interface IdFinder { @SuppressWarnings({"java:S1452", "TypeParameterExplicitlyExtendsObject"}) diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/auto/AbstractAutoIdFinder.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/auto/AbstractAutoIdFinder.java similarity index 95% rename from spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/auto/AbstractAutoIdFinder.java rename to spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/auto/AbstractAutoIdFinder.java index beb768f2..a34fe7d7 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/auto/AbstractAutoIdFinder.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/auto/AbstractAutoIdFinder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package software.xdev.spring.data.eclipse.store.repository.support.copier.id.strategy.auto; +package software.xdev.spring.data.eclipse.store.repository.support.id.strategy.auto; import java.util.Objects; import java.util.function.Supplier; @@ -21,9 +21,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import software.xdev.spring.data.eclipse.store.repository.support.copier.id.strategy.IdFinder; +import software.xdev.spring.data.eclipse.store.repository.support.id.strategy.IdFinder; +@SuppressWarnings("java:S119") public abstract class AbstractAutoIdFinder implements IdFinder { private static final Logger LOG = LoggerFactory.getLogger(AbstractAutoIdFinder.class); diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/auto/AutoIntegerIdFinder.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/auto/AutoIntegerIdFinder.java similarity index 97% rename from spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/auto/AutoIntegerIdFinder.java rename to spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/auto/AutoIntegerIdFinder.java index 0f4b4535..eee905b3 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/auto/AutoIntegerIdFinder.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/auto/AutoIntegerIdFinder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package software.xdev.spring.data.eclipse.store.repository.support.copier.id.strategy.auto; +package software.xdev.spring.data.eclipse.store.repository.support.id.strategy.auto; import java.util.function.Supplier; diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/auto/AutoLongIdFinder.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/auto/AutoLongIdFinder.java similarity index 97% rename from spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/auto/AutoLongIdFinder.java rename to spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/auto/AutoLongIdFinder.java index b3b41e56..2713212c 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/auto/AutoLongIdFinder.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/auto/AutoLongIdFinder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package software.xdev.spring.data.eclipse.store.repository.support.copier.id.strategy.auto; +package software.xdev.spring.data.eclipse.store.repository.support.id.strategy.auto; import java.util.function.Supplier; diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/auto/AutoStringIdFinder.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/auto/AutoStringIdFinder.java similarity index 97% rename from spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/auto/AutoStringIdFinder.java rename to spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/auto/AutoStringIdFinder.java index afc2cbca..75440144 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/copier/id/strategy/auto/AutoStringIdFinder.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/id/strategy/auto/AutoStringIdFinder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package software.xdev.spring.data.eclipse.store.repository.support.copier.id.strategy.auto; +package software.xdev.spring.data.eclipse.store.repository.support.id.strategy.auto; import java.util.function.Supplier; diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/reposyncer/RepositorySynchronizer.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/reposyncer/RepositorySynchronizer.java index 399552a2..8028edad 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/reposyncer/RepositorySynchronizer.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/reposyncer/RepositorySynchronizer.java @@ -17,7 +17,7 @@ import java.util.Collection; -import software.xdev.spring.data.eclipse.store.core.IdentitySet; +import software.xdev.spring.data.eclipse.store.repository.root.EntityData; /** @@ -29,7 +29,7 @@ public interface RepositorySynchronizer { /** - * @return a list of entity-lists that have been changed and now must be stored. + * @return a list of entity-data that have been changed and now must be stored. */ - Collection> syncAndReturnChangedObjectLists(Object objectToStore); + Collection> syncAndReturnChangedObjectLists(Object objectToStore); } diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/reposyncer/SimpleRepositorySynchronizer.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/reposyncer/SimpleRepositorySynchronizer.java index 81b16a28..b9857158 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/reposyncer/SimpleRepositorySynchronizer.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/support/reposyncer/SimpleRepositorySynchronizer.java @@ -23,18 +23,18 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import software.xdev.spring.data.eclipse.store.core.IdentitySet; -import software.xdev.spring.data.eclipse.store.repository.Root; +import software.xdev.spring.data.eclipse.store.repository.root.EntityData; +import software.xdev.spring.data.eclipse.store.repository.root.RootDataV2; public class SimpleRepositorySynchronizer implements RepositorySynchronizer { private static final Logger LOG = LoggerFactory.getLogger(SimpleRepositorySynchronizer.class); - private final Root root; - private final HashSet> listsToStore; + private final RootDataV2 root; + private final HashSet> listsToStore; private final ObjectGraphTraverser buildObjectGraphTraverser; - public SimpleRepositorySynchronizer(final Root root) + public SimpleRepositorySynchronizer(final RootDataV2 root) { this.root = root; this.listsToStore = new HashSet<>(); @@ -50,19 +50,20 @@ public SimpleRepositorySynchronizer(final Root root) return; } final Class objectInGraphClass = (Class)objectInGraph.getClass(); - final IdentitySet entityListForCurrentObject = this.root.getEntityList(objectInGraphClass); - if(entityListForCurrentObject != null - && !entityListForCurrentObject.contains(objectInGraph)) + final EntityData entityDataForCurrentObject = + this.root.getEntityData(objectInGraphClass); + if(entityDataForCurrentObject != null + && !entityDataForCurrentObject.getEntities().contains(objectInGraph)) { - entityListForCurrentObject.add(objectInGraph); - this.listsToStore.add(entityListForCurrentObject); + entityDataForCurrentObject.ensureEntityAndReturnObjectsToStore(objectInGraph); + this.listsToStore.add(entityDataForCurrentObject); } } ).buildObjectGraphTraverser(); } @Override - public Collection> syncAndReturnChangedObjectLists(final Object objectToStore) + public Collection> syncAndReturnChangedObjectLists(final Object objectToStore) { this.listsToStore.clear(); this.buildObjectGraphTraverser.traverse(objectToStore); @@ -70,7 +71,7 @@ public Collection> syncAndReturnChangedObjectLists(final Obj { LOG.trace("Amount of changed entities: {}", this.listsToStore.size()); } - final HashSet> setOfChangedObjects = new HashSet<>(this.listsToStore); + final HashSet> setOfChangedObjects = new HashSet<>(this.listsToStore); this.listsToStore.clear(); return setOfChangedObjects; } diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/helper/DummyEntityProvider.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/helper/DummyEntityProvider.java index 7be4d308..6de8b0cb 100644 --- a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/helper/DummyEntityProvider.java +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/helper/DummyEntityProvider.java @@ -19,20 +19,20 @@ import java.util.List; import software.xdev.spring.data.eclipse.store.core.EntityProvider; -import software.xdev.spring.data.eclipse.store.core.IdentitySet; +import software.xdev.spring.data.eclipse.store.repository.root.EntityData; -public class DummyEntityProvider extends EntityProvider +public class DummyEntityProvider extends EntityProvider { public DummyEntityProvider(final Collection collection) { super(); - final IdentitySet objects = new IdentitySet<>(); - objects.addAll(collection); - this.addIdentitySet(objects); + final EntityData objects = new EntityData<>(t -> null); + objects.getEntities().addAll(collection); + this.addEntityData(objects); } - public static DummyEntityProvider of(final E... entities) + public static DummyEntityProvider of(final E... entities) { return new DummyEntityProvider<>(List.of(entities)); } diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/TestConfiguration.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/TestConfiguration.java index 08974a22..345358eb 100644 --- a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/TestConfiguration.java +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/TestConfiguration.java @@ -69,4 +69,9 @@ public void handleContextClosed(final ContextClosedEvent event) throws IOExcepti this.getStorageInstance().stop(); FileSystemUtils.deleteRecursively(Path.of(this.storageDirectory)); } + + public String getStorageDirectory() + { + return this.storageDirectory; + } } diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/migration/MigrationTest.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/migration/MigrationTest.java new file mode 100644 index 00000000..0a70c1f3 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/migration/MigrationTest.java @@ -0,0 +1,87 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.migration; + +import static org.eclipse.store.storage.embedded.types.EmbeddedStorage.Foundation; + +import java.io.IOException; +import java.math.BigDecimal; +import java.nio.file.Path; +import java.util.List; + +import org.eclipse.store.storage.embedded.types.EmbeddedStorageManager; +import org.eclipse.store.storage.types.Storage; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.util.FileSystemUtils; + +import software.xdev.spring.data.eclipse.store.helper.TestData; +import software.xdev.spring.data.eclipse.store.helper.TestUtil; +import software.xdev.spring.data.eclipse.store.integration.isolated.IsolatedTestAnnotations; +import software.xdev.spring.data.eclipse.store.repository.Root; + + +@IsolatedTestAnnotations +@ContextConfiguration(classes = {MigrationTestConfiguration.class}) +class MigrationTest +{ + public static final User TEST_USER = new User(TestData.FIRST_NAME, BigDecimal.ONE); + + private final MigrationTestConfiguration configuration; + private final UserRepository userRepository; + + @Autowired + public MigrationTest(final MigrationTestConfiguration configuration, final UserRepository userRepository) + { + this.configuration = configuration; + this.userRepository = userRepository; + } + + @Test + void simpleMigrateFromV000ToV200() throws IOException + { + this.initOldData(); + TestUtil.doBeforeAndAfterRestartOfDatastore( + this.configuration, + () -> { + final List foundUsers = this.userRepository.findAll(); + Assertions.assertEquals(1, foundUsers.size()); + Assertions.assertEquals(TEST_USER, foundUsers.get(0)); + } + ); + } + + private void initOldData() throws IOException + { + // Delete already created data + this.configuration.getStorageInstance().stop(); + FileSystemUtils.deleteRecursively(Path.of(this.configuration.getStorageDirectory())); + + // Init old data + try(final EmbeddedStorageManager storageManager = + Foundation(Storage.Configuration(Storage.FileProvider(Path.of(this.configuration.getStorageDirectory())))) + .start()) + { + final Root oldRoot = new Root(); + oldRoot.createNewEntityList(User.class); + oldRoot.getEntityList(User.class).add(TEST_USER); + storageManager.setRoot(oldRoot); + storageManager.storeRoot(); + } + } +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/migration/MigrationTestConfiguration.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/migration/MigrationTestConfiguration.java new file mode 100644 index 00000000..d95988e6 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/migration/MigrationTestConfiguration.java @@ -0,0 +1,38 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.migration; + +import org.eclipse.store.integrations.spring.boot.types.configuration.EclipseStoreProperties; +import org.eclipse.store.integrations.spring.boot.types.factories.EmbeddedStorageFoundationFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; + +import software.xdev.spring.data.eclipse.store.integration.TestConfiguration; +import software.xdev.spring.data.eclipse.store.repository.config.EnableEclipseStoreRepositories; + + +@Configuration +@EnableEclipseStoreRepositories +public class MigrationTestConfiguration extends TestConfiguration +{ + @Autowired + protected MigrationTestConfiguration( + final EclipseStoreProperties defaultEclipseStoreProperties, + final EmbeddedStorageFoundationFactory defaultEclipseStoreProvider) + { + super(defaultEclipseStoreProperties, defaultEclipseStoreProvider); + } +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/migration/User.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/migration/User.java new file mode 100644 index 00000000..0bc36850 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/migration/User.java @@ -0,0 +1,94 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.migration; + +import java.math.BigDecimal; +import java.util.Objects; + +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + + +public class User +{ + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private int id; + + private String name; + + private BigDecimal balance; + + public User(final String name, final BigDecimal balance) + { + this.name = name; + this.balance = balance; + } + + public int getId() + { + return this.id; + } + + public void setId(final int id) + { + this.id = id; + } + + public BigDecimal getBalance() + { + return this.balance; + } + + public void setBalance(final BigDecimal balance) + { + this.balance = balance; + } + + public String getName() + { + return this.name; + } + + public void setName(final String name) + { + this.name = name; + } + + @Override + public boolean equals(final Object o) + { + if(this == o) + { + return true; + } + if(o == null || this.getClass() != o.getClass()) + { + return false; + } + final User user = (User)o; + return this.id == user.id && Objects.equals(this.name, user.name) && Objects.equals( + this.balance, + user.balance); + } + + @Override + public int hashCode() + { + return Objects.hash(this.id, this.name, this.balance); + } +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/migration/UserRepository.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/migration/UserRepository.java new file mode 100644 index 00000000..ba0c95c2 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/migration/UserRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.migration; + +import software.xdev.spring.data.eclipse.store.repository.interfaces.EclipseStoreRepository; + + +public interface UserRepository extends EclipseStoreRepository +{ +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/version/VersionedEntityWithUuid.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/version/VersionedEntityWithUuid.java index f631ff3f..128f3823 100644 --- a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/version/VersionedEntityWithUuid.java +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/version/VersionedEntityWithUuid.java @@ -20,6 +20,7 @@ import jakarta.persistence.Version; +@SuppressWarnings("java:S119") public class VersionedEntityWithUuid implements VersionedEntity { @Version diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorAndOrTest.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorAndOrTest.java index 9b575afb..2d55db8c 100644 --- a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorAndOrTest.java +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorAndOrTest.java @@ -47,7 +47,7 @@ static Stream generateDataWithCountOfFirstNameAndLastName() @ParameterizedTest @MethodSource("generateDataWithCountOfFirstNameAndLastName") void findByFirstNameAndLastName( - final EntityProvider entities, + final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = @@ -75,7 +75,7 @@ static Stream generateDataWithCountOfFirstNameOrLastName() @ParameterizedTest @MethodSource("generateDataWithCountOfFirstNameOrLastName") void findByFirstNameOrLastName( - final EntityProvider entities, + final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = @@ -103,7 +103,7 @@ static Stream generateDataWithCountOfId2AndFirstName() @ParameterizedTest @MethodSource("generateDataWithCountOfId2AndFirstName") void findByIdAndFirstName( - final EntityProvider entities, + final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByIdAndFirstName", int.class, String.class); @@ -130,7 +130,7 @@ static Stream generateDataWithCountOfIdAndFirstNameAndLastName() @ParameterizedTest @MethodSource("generateDataWithCountOfIdAndFirstNameAndLastName") void findByIdAndFirstNameAndLastName( - final EntityProvider entities, + final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod( @@ -161,7 +161,7 @@ static Stream generateDataWithCountOfIdOrFirstNameOrLastName() @ParameterizedTest @MethodSource("generateDataWithCountOfIdOrFirstNameOrLastName") void findByIdOrFirstNameOrLastName( - final EntityProvider entities, + final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod( @@ -195,7 +195,7 @@ static Stream generateDataWithCountOfIdAndFirstNameOrLastName() @ParameterizedTest @MethodSource("generateDataWithCountOfIdAndFirstNameOrLastName") void findByIdAndFirstNameOrLastName( - final EntityProvider entities, + final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod( @@ -224,7 +224,7 @@ void findByIdAndFirstNameOrLastName( @Disabled("This fails because AND is not prioritized higher then OR. Since this is a lot of work " + "in the criteria tree, this is postponed.") void findByLastNameOrIdAndFirstName( - final EntityProvider entities, + final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod( @@ -255,7 +255,7 @@ static Stream generateDataWithCountOfIdOrFirstNameAndLastName() @ParameterizedTest @MethodSource("generateDataWithCountOfIdOrFirstNameAndLastName") void findByIdOrFirstNameAndLastName( - final EntityProvider entities, + final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod( diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorBooleanTest.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorBooleanTest.java index 5ae9a771..0ffed6fd 100644 --- a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorBooleanTest.java +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorBooleanTest.java @@ -45,7 +45,7 @@ static Stream generateDataWithCountOfEnabled() @ParameterizedTest @MethodSource("generateDataWithCountOfEnabled") - void findByEnabledTrue(final EntityProvider entities, final int expectedCount) + void findByEnabledTrue(final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByEnabledTrue"); @@ -67,7 +67,7 @@ static Stream generateDataWithCountOfEnabledFalse() @ParameterizedTest @MethodSource("generateDataWithCountOfEnabledFalse") - void findByEnabledFalse(final EntityProvider entities, final int expectedCount) + void findByEnabledFalse(final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByEnabledFalse"); diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorCollectionTest.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorCollectionTest.java index f0bb1121..e99d6629 100644 --- a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorCollectionTest.java +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorCollectionTest.java @@ -54,7 +54,7 @@ static Stream generateDataWithCountOfIdIn() @ParameterizedTest @MethodSource("generateDataWithCountOfIdIn") - void findByIdIn(final EntityProvider entities, final int expectedCount) + void findByIdIn(final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByIdIn", Collection.class); @@ -86,7 +86,7 @@ static Stream generateDataWithCountOfIdNotIn() @ParameterizedTest @MethodSource("generateDataWithCountOfIdNotIn") - void findByIdNotIn(final EntityProvider entities, final int expectedCount) + void findByIdNotIn(final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByIdNotIn", Collection.class); diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorGreaterLessTest.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorGreaterLessTest.java index 53bb87d0..e3963d5d 100644 --- a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorGreaterLessTest.java +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorGreaterLessTest.java @@ -47,7 +47,7 @@ static Stream generateDataWithIdLessThan() @ParameterizedTest @MethodSource("generateDataWithIdLessThan") - void findByIdLessThan(final EntityProvider entities, final int expectedCount) + void findByIdLessThan(final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByIdLessThan", int.class); @@ -73,7 +73,7 @@ static Stream generateDataWithIdLessThanEqual() @ParameterizedTest @MethodSource("generateDataWithIdLessThanEqual") - void findByIdLessThanEqual(final EntityProvider entities, final int expectedCount) + void findByIdLessThanEqual(final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByIdLessThanEqual", int.class); @@ -99,7 +99,7 @@ static Stream generateDataWithIdGreaterThan() @ParameterizedTest @MethodSource("generateDataWithIdGreaterThan") - void findByIdGreaterThan(final EntityProvider entities, final int expectedCount) + void findByIdGreaterThan(final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByIdGreaterThan", int.class); @@ -125,7 +125,9 @@ static Stream generateDataWithIdGreaterThanEqual() @ParameterizedTest @MethodSource("generateDataWithIdGreaterThanEqual") - void findByIdGreaterThanEqual(final EntityProvider entities, final int expectedCount) + void findByIdGreaterThanEqual( + final EntityProvider entities, + final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByIdGreaterThanEqual", int.class); @@ -151,7 +153,7 @@ static Stream generateDataWithIdBetween() @ParameterizedTest @MethodSource("generateDataWithIdBetween") - void findByIdBetween(final EntityProvider entities, final int expectedCount) + void findByIdBetween(final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByIdBetween", int.class, int.class); @@ -166,7 +168,7 @@ void findByIdBetween(final EntityProvider entities, f @ParameterizedTest @MethodSource("generateDataWithIdBetween") - void findByIdBetweenInvalidRange(final EntityProvider entities) + void findByIdBetweenInvalidRange(final EntityProvider entities) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByIdBetween", int.class, int.class); @@ -192,7 +194,9 @@ static Stream generateDataWithFirstNameGreaterThan() @ParameterizedTest @MethodSource("generateDataWithFirstNameGreaterThan") - void findByFirstNameGreaterThan(final EntityProvider entities, final int expectedCount) + void findByFirstNameGreaterThan( + final EntityProvider entities, + final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByFirstNameGreaterThan", String.class); @@ -218,7 +222,9 @@ static Stream generateDataWithFirstNameLessThan() @ParameterizedTest @MethodSource("generateDataWithFirstNameLessThan") - void findByFirstNameLessThan(final EntityProvider entities, final int expectedCount) + void findByFirstNameLessThan( + final EntityProvider entities, + final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByFirstNameLessThan", String.class); diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorIsIsNotTest.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorIsIsNotTest.java index 55ee4273..69a040c3 100644 --- a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorIsIsNotTest.java +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorIsIsNotTest.java @@ -46,7 +46,7 @@ static Stream generateDataWithCountOfFirstName() @ParameterizedTest @MethodSource("generateDataWithCountOfFirstName") - void findByFirstName(final EntityProvider entities, final int expectedCount) + void findByFirstName(final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByFirstName", String.class); @@ -61,7 +61,7 @@ void findByFirstName(final EntityProvider entities, f @ParameterizedTest @MethodSource("generateDataWithCountOfFirstName") - void findByFirstNameIsNull(final EntityProvider entities) + void findByFirstNameIsNull(final EntityProvider entities) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByFirstName", String.class); @@ -84,7 +84,7 @@ static Stream generateDataWithCountOfId1() @ParameterizedTest @MethodSource("generateDataWithCountOfId1") void findById( - final EntityProvider entities, + final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findById", int.class); @@ -114,7 +114,7 @@ static Stream generateDataWithIncomparable() @ParameterizedTest @MethodSource("generateDataWithIncomparable") void findByIncomparable( - final EntityProvider entities, + final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod( @@ -132,7 +132,7 @@ void findByIncomparable( @ParameterizedTest @MethodSource("generateDataWithIncomparable") void findByIncomparableIsNotNull( - final EntityProvider entities, + final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod( @@ -160,7 +160,7 @@ static Stream generateDataWithIncomparableIsNull() @ParameterizedTest @MethodSource("generateDataWithIncomparableIsNull") void findByIncomparableIsNullDynamic( - final EntityProvider entities, + final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod( @@ -178,7 +178,7 @@ void findByIncomparableIsNullDynamic( @ParameterizedTest @MethodSource("generateDataWithIncomparableIsNull") void findByIncomparableIsNull( - final EntityProvider entities, + final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByIncomparableIsNull"); diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorStringTest.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorStringTest.java index 0225a07a..905ba506 100644 --- a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorStringTest.java +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/EclipseStoreQueryCreatorStringTest.java @@ -147,7 +147,7 @@ static Stream generateDataWithFirstNameStartingWith() @ParameterizedTest @MethodSource("generateDataWithFirstNameStartingWith") - void findByFirstNameStartingWith(final EntityProvider entities, final int expectedCount) + void findByFirstNameStartingWith(final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByFirstNameStartingWith", String.class); @@ -161,7 +161,7 @@ void findByFirstNameStartingWith(final EntityProvider entities, final @ParameterizedTest @MethodSource("generateDataWithFirstNameStartingWith") - void findByFirstNameEndingWith(final EntityProvider entities, final int expectedCount) + void findByFirstNameEndingWith(final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByFirstNameEndingWith", String.class); @@ -175,7 +175,7 @@ void findByFirstNameEndingWith(final EntityProvider entities, final in @ParameterizedTest @MethodSource("generateDataWithFirstNameStartingWith") - void findByFirstNameContainingWith(final EntityProvider entities, final int expectedCount) + void findByFirstNameContainingWith(final EntityProvider entities, final int expectedCount) throws NoSuchMethodException { final Method method = CustomerRepository.class.getMethod("findByFirstNameContaining", String.class); diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/QueryCreatorUtil.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/QueryCreatorUtil.java index ede9ee87..e7de149e 100644 --- a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/QueryCreatorUtil.java +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/QueryCreatorUtil.java @@ -62,7 +62,7 @@ TestData.LAST_NAME_ALTERNATIVE, new Incomparable(""), false), @SuppressWarnings("unchecked") public static Collection executeQuery( - final EntityProvider entities, + final EntityProvider entities, final Class domainClass, final Method method, final Object[] values) diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/executors/PageableSortableCollectionQuerierTest.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/executors/PageableSortableCollectionQuerierTest.java index 846c00ac..ae75e933 100644 --- a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/executors/PageableSortableCollectionQuerierTest.java +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/repository/query/executors/PageableSortableCollectionQuerierTest.java @@ -53,17 +53,17 @@ class PageableSortableCollectionQuerierTest } } - private static final EntityProvider DATA_CUSTOMERS_EMPTY = DummyEntityProvider.of(); - private static final EntityProvider DATA_CUSTOMERS_ONE = + private static final EntityProvider DATA_CUSTOMERS_EMPTY = DummyEntityProvider.of(); + private static final EntityProvider DATA_CUSTOMERS_ONE = DummyEntityProvider.of(new Customer(TestData.FIRST_NAME, TestData.LAST_NAME)); - private static final EntityProvider DATA_CUSTOMERS_TWO = DummyEntityProvider.of( + private static final EntityProvider DATA_CUSTOMERS_TWO = DummyEntityProvider.of( new Customer(TestData.FIRST_NAME, TestData.LAST_NAME), new Customer(TestData.FIRST_NAME_ALTERNATIVE, TestData.LAST_NAME_ALTERNATIVE)); - private static final EntityProvider DATA_CUSTOMERS_THREE = DummyEntityProvider.of( + private static final EntityProvider DATA_CUSTOMERS_THREE = DummyEntityProvider.of( new Customer(TestData.FIRST_NAME, TestData.LAST_NAME), new Customer(TestData.FIRST_NAME_ALTERNATIVE, TestData.LAST_NAME_ALTERNATIVE), new Customer(TestData.FIRST_NAME, TestData.LAST_NAME_ALTERNATIVE)); - private static final EntityProvider DATA_CUSTOMERS_DABC_ABCD = DummyEntityProvider.of( + private static final EntityProvider DATA_CUSTOMERS_DABC_ABCD = DummyEntityProvider.of( new Customer("D", "A"), new Customer("A", "B"), new Customer("B", "C"), @@ -85,7 +85,7 @@ static Stream generateData() @ParameterizedTest @MethodSource("generateData") - void getEntities_NoCriteria_NoPageable_NoSortable(final EntityProvider entities) + void getEntities_NoCriteria_NoPageable_NoSortable(final EntityProvider entities) { final PageableSortableCollectionQuerier querier = new PageableSortableCollectionQuerier<>( new DummyWorkingCopier<>(), @@ -96,7 +96,7 @@ void getEntities_NoCriteria_NoPageable_NoSortable(final EntityProvider @ParameterizedTest @MethodSource("generateData") - void getEntities_EmptyCriteria_NoPageable_NoSortable(final EntityProvider entities) + void getEntities_EmptyCriteria_NoPageable_NoSortable(final EntityProvider entities) { final PageableSortableCollectionQuerier querier = new PageableSortableCollectionQuerier<>( new DummyWorkingCopier<>(), @@ -107,7 +107,7 @@ void getEntities_EmptyCriteria_NoPageable_NoSortable(final EntityProvider entities) + void getEntities_EmptyCriteria_NoPageable_Sortable_SameSize(final EntityProvider entities) { final PageableSortableCollectionQuerier querier = new PageableSortableCollectionQuerier<>( new DummyWorkingCopier<>(), @@ -120,7 +120,7 @@ void getEntities_EmptyCriteria_NoPageable_Sortable_SameSize(final EntityProvider @ParameterizedTest @MethodSource("generateData") - void getEntities_EmptyCriteria_Pageable_Sortable_FixedSize(final EntityProvider entities) + void getEntities_EmptyCriteria_Pageable_Sortable_FixedSize(final EntityProvider entities) { final PageableSortableCollectionQuerier querier = new PageableSortableCollectionQuerier<>( new DummyWorkingCopier<>(), @@ -195,7 +195,7 @@ void getEntities_EmptyCriteria_NoPageable_Sortable_IsSortedByInvalidProperty() @ParameterizedTest @MethodSource("generateData") void getEntities_CriteriaFirstName_NoPageable_NoSortable( - final EntityProvider entities, + final EntityProvider entities, final int countOfEntitiesWithFirstName) { final PageableSortableCollectionQuerier querier = new PageableSortableCollectionQuerier<>(