From e161c42109c787300d61869b7f810c971f9e126e Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Fri, 27 Jan 2023 16:24:12 +0100
Subject: [PATCH 01/19] Add javadocs to codec classes

---
 .../codec/InternalPropertyCodecProvider.java  |  3 +++
 .../en2do/internal/codec/lang/ClassCodec.java | 19 +++++++++++++++++++
 .../internal/codec/map/GenericMapCodec.java   |  6 ++++++
 3 files changed, 28 insertions(+)

diff --git a/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java b/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java
index 320bc7d2..814ca85d 100644
--- a/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java
+++ b/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java
@@ -10,6 +10,9 @@
 
 import java.util.Map;
 
+/**
+ * This codec provider enables the usage of the en2do custom codecs and adds them to the CodecRegistry
+ */
 @Log
 public class InternalPropertyCodecProvider implements PropertyCodecProvider {
 
diff --git a/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java b/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java
index f183616a..32a97887 100644
--- a/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java
+++ b/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java
@@ -7,14 +7,29 @@
 import org.bson.codecs.DecoderContext;
 import org.bson.codecs.EncoderContext;
 
+/**
+ * ClassCodec is used to encode and decode java.lang.Class objects to mongodb document fields
+ */
 @SuppressWarnings("rawtypes")
 public class ClassCodec implements Codec<Class> {
 
+    /**
+     * See org.bson.codecs.Encoder
+     * @param writer the BSON writer to encode into
+     * @param value the value to encode
+     * @param encoderContext the encoder context
+     */
     @Override
     public void encode(BsonWriter writer, Class value, EncoderContext encoderContext) {
         writer.writeString(value.getName());
     }
 
+    /**
+     * See org.bson.codecs.Decoder
+     * @param reader         the BSON reader
+     * @param decoderContext the decoder context
+     * @return the decoded Class
+     */
     @Override
     public Class decode(BsonReader reader, DecoderContext decoderContext) {
         String className = reader.readString();
@@ -25,6 +40,10 @@ public Class decode(BsonReader reader, DecoderContext decoderContext) {
         }
     }
 
+    /**
+     * See org.bson.codecs.Encoder
+     * @return the class of the encoded class
+     */
     @Override
     public Class<Class> getEncoderClass() {
         return Class.class;
diff --git a/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java b/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java
index 8969e61a..5505403a 100644
--- a/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java
+++ b/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java
@@ -18,6 +18,12 @@
 import java.util.UUID;
 import java.util.logging.Level;
 
+/**
+ * This codec is used to allow different types as map keys, because
+ * mongodb pojo-codec only supports strings as map keys.
+ * @param <K> The type of the key of the generic map
+ * @param <T> The type of the value of the generic map
+ */
 @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
 @Log
 public class GenericMapCodec<K, T> implements Codec<Map<K, T>> {

From 3b6c1b374a15ab789d7c24e310b290a4eaa69287 Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Fri, 27 Jan 2023 16:40:08 +0100
Subject: [PATCH 02/19] Add javadocs to method options

---
 .../methods/pagination/Pagination.java        | 26 +++++++++++++++++
 .../en2do/repository/methods/sort/Limit.java  |  6 ++++
 .../en2do/repository/methods/sort/Skip.java   |  6 ++++
 .../en2do/repository/methods/sort/Sort.java   | 29 +++++++++++++++++++
 .../en2do/repository/methods/sort/SortBy.java |  9 ++++++
 .../repository/methods/sort/SortByArray.java  |  6 ++++
 .../methods/transform/Transform.java          |  8 +++++
 7 files changed, 90 insertions(+)

diff --git a/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java b/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java
index ccb0132c..1571fb9e 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java
@@ -8,10 +8,18 @@
 import java.util.HashMap;
 import java.util.Map;
 
+/**
+ * This object is used to provide simplified pagination in several repositories.
+ */
 @Getter
 @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
 public class Pagination {
 
+    /**
+     * Use this method to create a new pagination object.
+     * @param entitiesPerPage Sets the maximum entities per one page.
+     * @return The created Pagination object
+     */
     public static Pagination of(int entitiesPerPage) {
         return new Pagination(entitiesPerPage);
     }
@@ -27,15 +35,33 @@ private Pagination(int entitiesPerPage) {
         this.page = 1;
     }
 
+    /**
+     * Use this method to define the order / sorting by the given fields
+     * @param fieldName The field which is used to sort
+     * @param ascending The direction of the sorting
+     * @return The used Pagination object
+     */
     public Pagination order(String fieldName, boolean ascending) {
         pageDirectionMap.put(fieldName, ascending ? 1 : -1);
         return this;
     }
 
+    /**
+     * Use this method to define the order / sorting of the pagination,
+     * but sets the ascending value to "true"
+     * @param fieldName The field which is used to sort
+     * @return The used Pagination object
+     */
     public Pagination order(String fieldName) {
         return order(fieldName, true);
     }
 
+    /**
+     * Use this method to set the returned page. If the page doesn't exist,
+     * the method will just return an empty list.
+     * @param page The requested page
+     * @return The used Pagination object
+     */
     public Pagination page(long page) {
         this.page = page;
         return this;
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java
index 06aeeee6..1de7229f 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java
@@ -5,9 +5,15 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+/**
+ * This annotation is used to limit the amount of the returned entities in the List.
+ */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
 public @interface Limit {
 
+    /**
+     * @return The amount of the entities in the returned List.
+     */
     int value();
 }
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java
index c7d10f8a..2b7f5422 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java
@@ -5,9 +5,15 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+/**
+ * This annotation is used to skip the defined amount of entities by the given sorting.
+ */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
 public @interface Skip {
 
+    /**
+     * @return The amount of the skipped entities.
+     */
     int value();
 }
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java
index 3506d69c..62843937 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java
@@ -7,6 +7,9 @@
 import java.util.HashMap;
 import java.util.Map;
 
+/**
+ * This object is used to enable dynamic sorting, without defining the sorting options statically through annotations.
+ */
 @Getter
 @FieldDefaults(level = AccessLevel.PRIVATE)
 public class Sort {
@@ -16,6 +19,10 @@ public static Sort create() {
         return of();
     }
 
+    /**
+     * Use this method to create a new Sort object
+     * @return The new created sort object.
+     */
     public static Sort of() {
         return new Sort();
     }
@@ -30,20 +37,42 @@ private Sort() {
         this.skip = -1;
     }
 
+    /**
+     * Use this method to define the order / sorting by the given fields
+     * @param fieldName The field which is used to sort
+     * @param ascending The direction of the sorting
+     * @return The used Sort object
+     */
     public Sort order(String fieldName, boolean ascending) {
         fieldDirectionMap.put(fieldName, ascending ? 1 : -1);
         return this;
     }
 
+    /**
+     * Use this method to define the order / sorting by the given fields,
+     * but sets the ascending value to "true"
+     * @param fieldName The field which is used to sort
+     * @return The used Sort object
+     */
     public Sort order(String fieldName) {
         return order(fieldName, true);
     }
 
+    /**
+     * Use this method to set the limit of entities of the current sorting.
+     * @param limit The amount of the entities in the returned List.
+     * @return The used Sort object
+     */
     public Sort limit(int limit) {
         this.limit = limit;
         return this;
     }
 
+    /**
+     * Use this method to set the skipped entities of the current sorting.
+     * @param skip The amount of the entities, which should be skipped, before creating the List.
+     * @return The used Sort object
+     */
     public Sort skip(int skip) {
         this.skip = skip;
         return this;
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java
index 4059851e..a27d945a 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java
@@ -2,12 +2,21 @@
 
 import java.lang.annotation.*;
 
+/**
+ * This annotation is used to define the sorting of the given fields.
+ */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
 @Repeatable(value = SortByArray.class)
 public @interface SortBy {
 
+    /**
+     * @return The required field, which should be sorted.
+     */
     String field();
 
+    /**
+     * @return The optional direction, which defaults to ascending = "true".
+     */
     boolean ascending() default false;
 }
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java
index ec107f96..31014e0f 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java
@@ -5,9 +5,15 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+/**
+ * This annotation is used to create an array of the @SortBy annotation.
+ */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
 public @interface SortByArray {
 
+    /**
+     * @return The array of the @SortBy annotations.
+     */
     SortBy[] value();
 }
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java b/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java
index 6a2ce5c1..9309e1dd 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java
@@ -5,9 +5,17 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+/**
+ * This annotation is used to "rename" a method name of the repository.
+ * If you use this annotation, keep in mind, that the validation uses the
+ * value of the annotation instead of the method name itself.
+ */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
 public @interface Transform {
 
+    /**
+     * @return The "real" method declaration according to the en2do specification.
+     */
     String value();
 }

From aecab6369c88e96efc8ed76708b46d9333e5d097 Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Fri, 27 Jan 2023 16:50:32 +0100
Subject: [PATCH 03/19] Add javadocs to repository options

---
 .../koboo/en2do/repository/AppendMethodAsComment.java |  4 +++-
 .../java/eu/koboo/en2do/repository/Collection.java    | 11 +++++++----
 .../koboo/en2do/repository/DropEntitiesOnStart.java   |  5 ++++-
 .../eu/koboo/en2do/repository/DropIndexesOnStart.java |  5 ++++-
 .../eu/koboo/en2do/repository/SeparateEntityId.java   |  5 +++++
 5 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java b/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java
index 2877317d..bf90104f 100644
--- a/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java
+++ b/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java
@@ -2,7 +2,9 @@
 
 import java.lang.annotation.*;
 
-@Inherited
+/**
+ * This annotation appends the repository method name to the mongodb find queries.
+ */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
 public @interface AppendMethodAsComment {
diff --git a/src/main/java/eu/koboo/en2do/repository/Collection.java b/src/main/java/eu/koboo/en2do/repository/Collection.java
index 804b2aca..c0e7312d 100644
--- a/src/main/java/eu/koboo/en2do/repository/Collection.java
+++ b/src/main/java/eu/koboo/en2do/repository/Collection.java
@@ -1,13 +1,16 @@
 package eu.koboo.en2do.repository;
 
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
+import java.lang.annotation.*;
 
+/**
+ * This annotation defines the collection name of the repository in the mongodb.
+ */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
 public @interface Collection {
 
+    /**
+     * @return The collection name in the mongodb.
+     */
     String value();
 }
diff --git a/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java b/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java
index b77b04c4..03b21436 100644
--- a/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java
+++ b/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java
@@ -2,7 +2,10 @@
 
 import java.lang.annotation.*;
 
-@Inherited
+/**
+ * This annotation drops all previously created entities, when the annotated repository is created.
+ * CAUTION: This will delete all entities permanently!
+ */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
 public @interface DropEntitiesOnStart {
diff --git a/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java b/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java
index ba2eed9a..d21f25c9 100644
--- a/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java
+++ b/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java
@@ -2,7 +2,10 @@
 
 import java.lang.annotation.*;
 
-@Inherited
+/**
+ * This annotation drops all previously created indexes, when the annotated repository is created.
+ * CAUTION: This will delete all indexes permanently!
+ */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
 public @interface DropIndexesOnStart {
diff --git a/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java b/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java
index 9d097aa0..b444a458 100644
--- a/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java
+++ b/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java
@@ -5,6 +5,11 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+/**
+ * This annotation separates the "_id" field of the mongodb document and the "@Id" annotated field of the
+ * entity. If this annotation is NOT used on the repository, the "@Id" field can't be annotated with "@NonIndex", that
+ * will throw an exception.
+ */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
 public @interface SeparateEntityId {

From 92e19d628b097de063a3b8d6cae28a5d523bdd2d Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Fri, 27 Jan 2023 17:00:54 +0100
Subject: [PATCH 04/19] Add javadocs to the repository interface

---
 .../eu/koboo/en2do/repository/Repository.java | 90 ++++++++++++++++++-
 1 file changed, 88 insertions(+), 2 deletions(-)

diff --git a/src/main/java/eu/koboo/en2do/repository/Repository.java b/src/main/java/eu/koboo/en2do/repository/Repository.java
index c43262d3..ee1bf59f 100644
--- a/src/main/java/eu/koboo/en2do/repository/Repository.java
+++ b/src/main/java/eu/koboo/en2do/repository/Repository.java
@@ -5,40 +5,126 @@
 
 import java.util.List;
 
+/**
+ * The default Repository interface, which predefines several useful methods.
+ * @param <E> The generic type of the Entity
+ * @param <ID> The generic type of the field annotated with "@Id" in the Entity
+ */
 @SuppressWarnings("unused")
 public interface Repository<E, ID> {
 
+    /**
+     * This method counts all documents of the collection in the mongodb.
+     * @return The amount of total entities in this repository.
+     */
     long countAll();
 
+    /**
+     * This method deletes the given entity, by filtering with the entity's "@Id" field/unique identifier.
+     * @param entity The entity, which should be deleted.
+     * @return true, if the entity was deleted successfully.
+     */
     boolean delete(E entity);
 
+    /**
+     * This method deletes all entities of the given list, filtering like the "#delete(E entity)" method.
+     * @param entityList The List with the entities, which should be deleted.
+     * @return true, if all entities were deleted successfully.
+     */
     boolean deleteAll(List<E> entityList);
 
+    /**
+     * This method deletes the entity with the given identifier, filtering like the "#delete(E entity)" method.
+     * @param identifier The unique identifier of the entity, which should be deleted.
+     * @return true, if the entity was deleted successfully.
+     */
     boolean deleteById(ID identifier);
 
+    /**
+     * Drops / deletes all entities of the repository.
+     * @return true, if all entities were deleted successfully.
+     */
     boolean drop();
 
+    /**
+     * Checks if the given entity exists in the repository, by filtering with the entity's
+     * "@Id" field/unique identifier.
+     * @param entity The entity, which should be checked.
+     * @return true, if the entity exists in the collection.
+     */
     boolean exists(E entity);
 
+    /**
+     * Checks if an entity with the given unique identifier exists in the repository, like the "#exists(E entity)" method.
+     * @param identifier The identifier of the entity, which should be checked.
+     * @return true, if an entity with the given identifier exists in the collection.
+     */
     boolean existsById(ID identifier);
 
+    /**
+     * Finds all entities of the collection
+     * @return A List with all entities of the repository.
+     */
     List<E> findAll();
 
+    /**
+     * Find the first entity with the given unique identifier.
+     * If the entity is not found, "null" is returned.
+     * @param identifier The unique identifier of the entity, which is used to filter.
+     * @return The found entity, if it exists, or "null" if it not exists.
+     */
     E findFirstById(ID identifier);
 
+    /**
+     * @return The collection name, defined by the "@Collection" annotation of the repository.
+     */
     String getCollectionName();
 
+    /**
+     * @return The Class of the entity of the repository.
+     */
     Class<E> getEntityClass();
 
+    /**
+     * @return The Class of the unique identifier of the entity of the repository.
+     */
     Class<ID> getEntityUniqueIdClass();
 
+    /**
+     * This method is used to get the unique identifier of the given entity.
+     * If the entity doesn't have a unique identifier, a NullPointerException is thrown.
+     * @param entity The entity, which unique identifier, should be returned
+     * @return The unique identifier of the given entity.
+     */
     ID getUniqueId(E entity);
 
-    List<E> pageAll(Pagination pager);
-
+    /**
+     * This method applies the pagination of all entities of the repository.
+     * @param pagination The pagination, which is used to page the entities.
+     * @return A List with the paged entities.
+     */
+    List<E> pageAll(Pagination pagination);
+
+    /**
+     * Saves the given entity to the database.
+     * If the entity exists, the existing document is updated.
+     * If the entity doesn't exist, a new document is created.
+     * @param entity The entity, which should be saved.
+     * @return true, if the entity was successfully saved.
+     */
     boolean save(E entity);
 
+    /**
+     * Saves all entities of the given List to the database.
+     * @param entityList A List of the entities, which should be saved
+     * @return true, if the entities were successfully saved.
+     */
     boolean saveAll(List<E> entityList);
 
+    /**
+     * This method applies the Sort object of all entities of the repository.
+     * @param sort The Sort object, which should be used to sort all entities.
+     * @return A List with the sorted entities.
+     */
     List<E> sortAll(Sort sort);
 }

From 61804284cbff6d8fc0c819d323a832170152bd24 Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Fri, 27 Jan 2023 17:12:17 +0100
Subject: [PATCH 05/19] Add more javadocs + documentation links to gitbook

---
 src/main/java/eu/koboo/en2do/Credentials.java              | 6 ++++++
 src/main/java/eu/koboo/en2do/MongoManager.java             | 6 ++++++
 .../eu/koboo/en2do/repository/AppendMethodAsComment.java   | 1 +
 src/main/java/eu/koboo/en2do/repository/Collection.java    | 1 +
 .../eu/koboo/en2do/repository/DropEntitiesOnStart.java     | 1 +
 .../java/eu/koboo/en2do/repository/DropIndexesOnStart.java | 1 +
 src/main/java/eu/koboo/en2do/repository/Repository.java    | 2 ++
 .../java/eu/koboo/en2do/repository/SeparateEntityId.java   | 1 +
 src/main/java/eu/koboo/en2do/repository/entity/Id.java     | 4 ++++
 .../java/eu/koboo/en2do/repository/entity/NonIndex.java    | 3 +++
 .../eu/koboo/en2do/repository/entity/TransformField.java   | 7 +++++++
 .../java/eu/koboo/en2do/repository/entity/Transient.java   | 5 +++++
 .../repository/entity/compound/CompoundIndexArray.java     | 6 ++++++
 .../eu/koboo/en2do/repository/entity/ttl/TTLIndex.java     | 6 ++++++
 .../koboo/en2do/repository/entity/ttl/TTLIndexArray.java   | 6 ++++++
 .../en2do/repository/methods/pagination/Pagination.java    | 1 +
 .../java/eu/koboo/en2do/repository/methods/sort/Limit.java | 1 +
 .../java/eu/koboo/en2do/repository/methods/sort/Skip.java  | 1 +
 .../java/eu/koboo/en2do/repository/methods/sort/Sort.java  | 1 +
 .../eu/koboo/en2do/repository/methods/sort/SortBy.java     | 1 +
 .../koboo/en2do/repository/methods/sort/SortByArray.java   | 1 +
 .../en2do/repository/methods/transform/Transform.java      | 1 +
 22 files changed, 63 insertions(+)

diff --git a/src/main/java/eu/koboo/en2do/Credentials.java b/src/main/java/eu/koboo/en2do/Credentials.java
index a1da9e14..0985addf 100644
--- a/src/main/java/eu/koboo/en2do/Credentials.java
+++ b/src/main/java/eu/koboo/en2do/Credentials.java
@@ -8,6 +8,12 @@
 import java.util.Locale;
 import java.util.Properties;
 
+/**
+ * This object is used to simplify creating credentials to the mongodb server.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-mongomanager">...</a>
+ * @param connectString The connection string to the mongodb database server
+ * @param database The database, which should be used
+ */
 @SuppressWarnings("unused")
 public record Credentials(String connectString, String database) {
 
diff --git a/src/main/java/eu/koboo/en2do/MongoManager.java b/src/main/java/eu/koboo/en2do/MongoManager.java
index d6d7d248..5f414612 100644
--- a/src/main/java/eu/koboo/en2do/MongoManager.java
+++ b/src/main/java/eu/koboo/en2do/MongoManager.java
@@ -56,6 +56,12 @@
 import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
 import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
 
+/**
+ * This object is the main entry point of en2do.
+ * The connection will be opened on construction.
+ * Keep in mind, that you should call "#MongoManger#close()" on application shutdown/termination.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-mongomanager">...</a>
+ */
 @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
 public class MongoManager {
 
diff --git a/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java b/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java
index bf90104f..b52b3edf 100644
--- a/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java
+++ b/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java
@@ -4,6 +4,7 @@
 
 /**
  * This annotation appends the repository method name to the mongodb find queries.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/repository-options/appendmethodascomment">...</a>
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
diff --git a/src/main/java/eu/koboo/en2do/repository/Collection.java b/src/main/java/eu/koboo/en2do/repository/Collection.java
index c0e7312d..d82bc5ae 100644
--- a/src/main/java/eu/koboo/en2do/repository/Collection.java
+++ b/src/main/java/eu/koboo/en2do/repository/Collection.java
@@ -4,6 +4,7 @@
 
 /**
  * This annotation defines the collection name of the repository in the mongodb.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-repository">...</a>
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
diff --git a/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java b/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java
index 03b21436..d2acdba1 100644
--- a/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java
+++ b/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java
@@ -5,6 +5,7 @@
 /**
  * This annotation drops all previously created entities, when the annotated repository is created.
  * CAUTION: This will delete all entities permanently!
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/repository-options/dropentitiesonstart">...</a>
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
diff --git a/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java b/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java
index d21f25c9..b8f8d4d9 100644
--- a/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java
+++ b/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java
@@ -5,6 +5,7 @@
 /**
  * This annotation drops all previously created indexes, when the annotated repository is created.
  * CAUTION: This will delete all indexes permanently!
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/repository-options/dropindexesonstart">...</a>
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
diff --git a/src/main/java/eu/koboo/en2do/repository/Repository.java b/src/main/java/eu/koboo/en2do/repository/Repository.java
index ee1bf59f..5c90c7dd 100644
--- a/src/main/java/eu/koboo/en2do/repository/Repository.java
+++ b/src/main/java/eu/koboo/en2do/repository/Repository.java
@@ -7,6 +7,8 @@
 
 /**
  * The default Repository interface, which predefines several useful methods.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/methods/predefined-methods">...</a>
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-repository">...</a>
  * @param <E> The generic type of the Entity
  * @param <ID> The generic type of the field annotated with "@Id" in the Entity
  */
diff --git a/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java b/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java
index b444a458..bb091cf7 100644
--- a/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java
+++ b/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java
@@ -9,6 +9,7 @@
  * This annotation separates the "_id" field of the mongodb document and the "@Id" annotated field of the
  * entity. If this annotation is NOT used on the repository, the "@Id" field can't be annotated with "@NonIndex", that
  * will throw an exception.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/repository-options/separateentityid">...</a>
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
diff --git a/src/main/java/eu/koboo/en2do/repository/entity/Id.java b/src/main/java/eu/koboo/en2do/repository/entity/Id.java
index b8d24045..8c3761e9 100644
--- a/src/main/java/eu/koboo/en2do/repository/entity/Id.java
+++ b/src/main/java/eu/koboo/en2do/repository/entity/Id.java
@@ -2,6 +2,10 @@
 
 import java.lang.annotation.*;
 
+/**
+ * This annotation defines the unique identifier of the entity.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/index/identifier-index">...</a>
+ */
 @Inherited
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.FIELD)
diff --git a/src/main/java/eu/koboo/en2do/repository/entity/NonIndex.java b/src/main/java/eu/koboo/en2do/repository/entity/NonIndex.java
index 8f266bff..bfb5bf29 100644
--- a/src/main/java/eu/koboo/en2do/repository/entity/NonIndex.java
+++ b/src/main/java/eu/koboo/en2do/repository/entity/NonIndex.java
@@ -2,6 +2,9 @@
 
 import java.lang.annotation.*;
 
+/**
+ * This annotation disables the creating of the unique index of the "@Id" field.
+ */
 @Inherited
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.FIELD)
diff --git a/src/main/java/eu/koboo/en2do/repository/entity/TransformField.java b/src/main/java/eu/koboo/en2do/repository/entity/TransformField.java
index e502dfc7..f920b059 100644
--- a/src/main/java/eu/koboo/en2do/repository/entity/TransformField.java
+++ b/src/main/java/eu/koboo/en2do/repository/entity/TransformField.java
@@ -2,10 +2,17 @@
 
 import java.lang.annotation.*;
 
+/**
+ * This annotation "renames" a field in the mongodb document, to the name of the value attribute.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/transformfield">...</a>
+ */
 @Inherited
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.FIELD)
 public @interface TransformField {
 
+    /**
+     * @return The name of the field in the document.
+     */
     String value();
 }
diff --git a/src/main/java/eu/koboo/en2do/repository/entity/Transient.java b/src/main/java/eu/koboo/en2do/repository/entity/Transient.java
index 069748e6..6353c433 100644
--- a/src/main/java/eu/koboo/en2do/repository/entity/Transient.java
+++ b/src/main/java/eu/koboo/en2do/repository/entity/Transient.java
@@ -2,6 +2,11 @@
 
 import java.lang.annotation.*;
 
+/**
+ * This annotation sets a field "ignored" by the database. All fields with this field, aren't saved to
+ * the document of the entity. The value of the field will get lost, by saving and getting it from the database.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/transient">...</a>
+ */
 @Inherited
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.FIELD)
diff --git a/src/main/java/eu/koboo/en2do/repository/entity/compound/CompoundIndexArray.java b/src/main/java/eu/koboo/en2do/repository/entity/compound/CompoundIndexArray.java
index 7c777893..da2397e0 100644
--- a/src/main/java/eu/koboo/en2do/repository/entity/compound/CompoundIndexArray.java
+++ b/src/main/java/eu/koboo/en2do/repository/entity/compound/CompoundIndexArray.java
@@ -2,10 +2,16 @@
 
 import java.lang.annotation.*;
 
+/**
+ * This annotation is used to create an array of the @CompoundIndex annotation.
+ */
 @Inherited
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
 public @interface CompoundIndexArray {
 
+    /**
+     * @return The array of the @CompoundIndex annotations.
+     */
     CompoundIndex[] value();
 }
diff --git a/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndex.java b/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndex.java
index 6aa6d06d..135e0897 100644
--- a/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndex.java
+++ b/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndex.java
@@ -3,6 +3,12 @@
 import java.lang.annotation.*;
 import java.util.concurrent.TimeUnit;
 
+/**
+ * This annotation allows setting time-tp-live on specific fields of type "java.util.Date". MongoDB will delete
+ * them by itself, so the application doesn't need a repeating task other something similar, to check for the time value
+ * of the given field.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/index/ttl-index">...</a>
+ */
 @Inherited
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
diff --git a/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndexArray.java b/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndexArray.java
index 52fc2418..8847e69b 100644
--- a/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndexArray.java
+++ b/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndexArray.java
@@ -2,10 +2,16 @@
 
 import java.lang.annotation.*;
 
+/**
+ * This annotation is used to create an array of the @TTLIndex annotation.
+ */
 @Inherited
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
 public @interface TTLIndexArray {
 
+    /**
+     * @return The array of the @TTLIndex annotations.
+     */
     TTLIndex[] value();
 }
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java b/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java
index 1571fb9e..3306683f 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java
@@ -10,6 +10,7 @@
 
 /**
  * This object is used to provide simplified pagination in several repositories.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/pagination">...</a>
  */
 @Getter
 @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java
index 1de7229f..7f9df5c5 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java
@@ -7,6 +7,7 @@
 
 /**
  * This annotation is used to limit the amount of the returned entities in the List.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/sorting/sorting-by-annotation">...</a>
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java
index 2b7f5422..44166b55 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java
@@ -7,6 +7,7 @@
 
 /**
  * This annotation is used to skip the defined amount of entities by the given sorting.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/sorting/sorting-by-annotation">...</a>
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java
index 62843937..754c2a09 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java
@@ -9,6 +9,7 @@
 
 /**
  * This object is used to enable dynamic sorting, without defining the sorting options statically through annotations.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/sorting/sorting-by-parameter">...</a>
  */
 @Getter
 @FieldDefaults(level = AccessLevel.PRIVATE)
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java
index a27d945a..6a224ae2 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java
@@ -4,6 +4,7 @@
 
 /**
  * This annotation is used to define the sorting of the given fields.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/sorting/sorting-by-annotation">...</a>
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java
index 31014e0f..0496ea67 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java
@@ -7,6 +7,7 @@
 
 /**
  * This annotation is used to create an array of the @SortBy annotation.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/sorting/sorting-by-annotation">...</a>
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java b/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java
index 9309e1dd..8ff5ee69 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java
@@ -9,6 +9,7 @@
  * This annotation is used to "rename" a method name of the repository.
  * If you use this annotation, keep in mind, that the validation uses the
  * value of the annotation instead of the method name itself.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/transform">...</a>
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)

From 942e5ad726cce3b0c64839993092907be50856f3 Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Fri, 27 Jan 2023 19:48:39 +0100
Subject: [PATCH 06/19] Delete unused ObjectIdUtils

---
 .../eu/koboo/en2do/utility/ObjectIdUtils.java  | 18 ------------------
 1 file changed, 18 deletions(-)
 delete mode 100644 src/main/java/eu/koboo/en2do/utility/ObjectIdUtils.java

diff --git a/src/main/java/eu/koboo/en2do/utility/ObjectIdUtils.java b/src/main/java/eu/koboo/en2do/utility/ObjectIdUtils.java
deleted file mode 100644
index 9fadae7c..00000000
--- a/src/main/java/eu/koboo/en2do/utility/ObjectIdUtils.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package eu.koboo.en2do.utility;
-
-import lombok.experimental.UtilityClass;
-import org.bson.types.ObjectId;
-
-@UtilityClass
-public class ObjectIdUtils {
-
-    public ObjectId of(Object object) {
-        if (object instanceof ObjectId objectId) {
-            return objectId;
-        }
-        if (object instanceof String string) {
-            return new ObjectId(string);
-        }
-        return new ObjectId(String.valueOf(object));
-    }
-}

From dcca06c0dfeb5037b378839ec3f1e2168d65e0c8 Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Fri, 27 Jan 2023 19:49:54 +0100
Subject: [PATCH 07/19] Optimize imports + Reformat code

---
 src/main/java/eu/koboo/en2do/Credentials.java   |  3 ++-
 .../en2do/internal/codec/lang/ClassCodec.java   |  7 +++++--
 .../internal/codec/map/GenericMapCodec.java     |  1 +
 .../en2do/repository/AppendMethodAsComment.java |  5 ++++-
 .../eu/koboo/en2do/repository/Collection.java   |  5 ++++-
 .../en2do/repository/DropEntitiesOnStart.java   |  5 ++++-
 .../en2do/repository/DropIndexesOnStart.java    |  5 ++++-
 .../eu/koboo/en2do/repository/Repository.java   | 17 ++++++++++++++++-
 .../methods/pagination/Pagination.java          |  4 ++++
 .../en2do/repository/methods/sort/Sort.java     |  5 +++++
 10 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/src/main/java/eu/koboo/en2do/Credentials.java b/src/main/java/eu/koboo/en2do/Credentials.java
index 0985addf..a45e567d 100644
--- a/src/main/java/eu/koboo/en2do/Credentials.java
+++ b/src/main/java/eu/koboo/en2do/Credentials.java
@@ -11,8 +11,9 @@
 /**
  * This object is used to simplify creating credentials to the mongodb server.
  * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-mongomanager">...</a>
+ *
  * @param connectString The connection string to the mongodb database server
- * @param database The database, which should be used
+ * @param database      The database, which should be used
  */
 @SuppressWarnings("unused")
 public record Credentials(String connectString, String database) {
diff --git a/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java b/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java
index 32a97887..9a1b971e 100644
--- a/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java
+++ b/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java
@@ -15,8 +15,9 @@ public class ClassCodec implements Codec<Class> {
 
     /**
      * See org.bson.codecs.Encoder
-     * @param writer the BSON writer to encode into
-     * @param value the value to encode
+     *
+     * @param writer         the BSON writer to encode into
+     * @param value          the value to encode
      * @param encoderContext the encoder context
      */
     @Override
@@ -26,6 +27,7 @@ public void encode(BsonWriter writer, Class value, EncoderContext encoderContext
 
     /**
      * See org.bson.codecs.Decoder
+     *
      * @param reader         the BSON reader
      * @param decoderContext the decoder context
      * @return the decoded Class
@@ -42,6 +44,7 @@ public Class decode(BsonReader reader, DecoderContext decoderContext) {
 
     /**
      * See org.bson.codecs.Encoder
+     *
      * @return the class of the encoded class
      */
     @Override
diff --git a/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java b/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java
index 5505403a..f331dff9 100644
--- a/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java
+++ b/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java
@@ -21,6 +21,7 @@
 /**
  * This codec is used to allow different types as map keys, because
  * mongodb pojo-codec only supports strings as map keys.
+ *
  * @param <K> The type of the key of the generic map
  * @param <T> The type of the value of the generic map
  */
diff --git a/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java b/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java
index b52b3edf..7ad8d8c9 100644
--- a/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java
+++ b/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java
@@ -1,6 +1,9 @@
 package eu.koboo.en2do.repository;
 
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
  * This annotation appends the repository method name to the mongodb find queries.
diff --git a/src/main/java/eu/koboo/en2do/repository/Collection.java b/src/main/java/eu/koboo/en2do/repository/Collection.java
index d82bc5ae..193a71a2 100644
--- a/src/main/java/eu/koboo/en2do/repository/Collection.java
+++ b/src/main/java/eu/koboo/en2do/repository/Collection.java
@@ -1,6 +1,9 @@
 package eu.koboo.en2do.repository;
 
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
  * This annotation defines the collection name of the repository in the mongodb.
diff --git a/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java b/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java
index d2acdba1..c5cbadac 100644
--- a/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java
+++ b/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java
@@ -1,6 +1,9 @@
 package eu.koboo.en2do.repository;
 
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
  * This annotation drops all previously created entities, when the annotated repository is created.
diff --git a/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java b/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java
index b8f8d4d9..d9982554 100644
--- a/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java
+++ b/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java
@@ -1,6 +1,9 @@
 package eu.koboo.en2do.repository;
 
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
  * This annotation drops all previously created indexes, when the annotated repository is created.
diff --git a/src/main/java/eu/koboo/en2do/repository/Repository.java b/src/main/java/eu/koboo/en2do/repository/Repository.java
index 5c90c7dd..f24614df 100644
--- a/src/main/java/eu/koboo/en2do/repository/Repository.java
+++ b/src/main/java/eu/koboo/en2do/repository/Repository.java
@@ -9,7 +9,8 @@
  * The default Repository interface, which predefines several useful methods.
  * See documentation: <a href="https://koboo.gitbook.io/en2do/methods/predefined-methods">...</a>
  * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-repository">...</a>
- * @param <E> The generic type of the Entity
+ *
+ * @param <E>  The generic type of the Entity
  * @param <ID> The generic type of the field annotated with "@Id" in the Entity
  */
 @SuppressWarnings("unused")
@@ -17,12 +18,14 @@ public interface Repository<E, ID> {
 
     /**
      * This method counts all documents of the collection in the mongodb.
+     *
      * @return The amount of total entities in this repository.
      */
     long countAll();
 
     /**
      * This method deletes the given entity, by filtering with the entity's "@Id" field/unique identifier.
+     *
      * @param entity The entity, which should be deleted.
      * @return true, if the entity was deleted successfully.
      */
@@ -30,6 +33,7 @@ public interface Repository<E, ID> {
 
     /**
      * This method deletes all entities of the given list, filtering like the "#delete(E entity)" method.
+     *
      * @param entityList The List with the entities, which should be deleted.
      * @return true, if all entities were deleted successfully.
      */
@@ -37,6 +41,7 @@ public interface Repository<E, ID> {
 
     /**
      * This method deletes the entity with the given identifier, filtering like the "#delete(E entity)" method.
+     *
      * @param identifier The unique identifier of the entity, which should be deleted.
      * @return true, if the entity was deleted successfully.
      */
@@ -44,6 +49,7 @@ public interface Repository<E, ID> {
 
     /**
      * Drops / deletes all entities of the repository.
+     *
      * @return true, if all entities were deleted successfully.
      */
     boolean drop();
@@ -51,6 +57,7 @@ public interface Repository<E, ID> {
     /**
      * Checks if the given entity exists in the repository, by filtering with the entity's
      * "@Id" field/unique identifier.
+     *
      * @param entity The entity, which should be checked.
      * @return true, if the entity exists in the collection.
      */
@@ -58,6 +65,7 @@ public interface Repository<E, ID> {
 
     /**
      * Checks if an entity with the given unique identifier exists in the repository, like the "#exists(E entity)" method.
+     *
      * @param identifier The identifier of the entity, which should be checked.
      * @return true, if an entity with the given identifier exists in the collection.
      */
@@ -65,6 +73,7 @@ public interface Repository<E, ID> {
 
     /**
      * Finds all entities of the collection
+     *
      * @return A List with all entities of the repository.
      */
     List<E> findAll();
@@ -72,6 +81,7 @@ public interface Repository<E, ID> {
     /**
      * Find the first entity with the given unique identifier.
      * If the entity is not found, "null" is returned.
+     *
      * @param identifier The unique identifier of the entity, which is used to filter.
      * @return The found entity, if it exists, or "null" if it not exists.
      */
@@ -95,6 +105,7 @@ public interface Repository<E, ID> {
     /**
      * This method is used to get the unique identifier of the given entity.
      * If the entity doesn't have a unique identifier, a NullPointerException is thrown.
+     *
      * @param entity The entity, which unique identifier, should be returned
      * @return The unique identifier of the given entity.
      */
@@ -102,6 +113,7 @@ public interface Repository<E, ID> {
 
     /**
      * This method applies the pagination of all entities of the repository.
+     *
      * @param pagination The pagination, which is used to page the entities.
      * @return A List with the paged entities.
      */
@@ -111,6 +123,7 @@ public interface Repository<E, ID> {
      * Saves the given entity to the database.
      * If the entity exists, the existing document is updated.
      * If the entity doesn't exist, a new document is created.
+     *
      * @param entity The entity, which should be saved.
      * @return true, if the entity was successfully saved.
      */
@@ -118,6 +131,7 @@ public interface Repository<E, ID> {
 
     /**
      * Saves all entities of the given List to the database.
+     *
      * @param entityList A List of the entities, which should be saved
      * @return true, if the entities were successfully saved.
      */
@@ -125,6 +139,7 @@ public interface Repository<E, ID> {
 
     /**
      * This method applies the Sort object of all entities of the repository.
+     *
      * @param sort The Sort object, which should be used to sort all entities.
      * @return A List with the sorted entities.
      */
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java b/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java
index 3306683f..aca46ebd 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java
@@ -18,6 +18,7 @@ public class Pagination {
 
     /**
      * Use this method to create a new pagination object.
+     *
      * @param entitiesPerPage Sets the maximum entities per one page.
      * @return The created Pagination object
      */
@@ -38,6 +39,7 @@ private Pagination(int entitiesPerPage) {
 
     /**
      * Use this method to define the order / sorting by the given fields
+     *
      * @param fieldName The field which is used to sort
      * @param ascending The direction of the sorting
      * @return The used Pagination object
@@ -50,6 +52,7 @@ public Pagination order(String fieldName, boolean ascending) {
     /**
      * Use this method to define the order / sorting of the pagination,
      * but sets the ascending value to "true"
+     *
      * @param fieldName The field which is used to sort
      * @return The used Pagination object
      */
@@ -60,6 +63,7 @@ public Pagination order(String fieldName) {
     /**
      * Use this method to set the returned page. If the page doesn't exist,
      * the method will just return an empty list.
+     *
      * @param page The requested page
      * @return The used Pagination object
      */
diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java
index 754c2a09..6f4b4381 100644
--- a/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java
+++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java
@@ -22,6 +22,7 @@ public static Sort create() {
 
     /**
      * Use this method to create a new Sort object
+     *
      * @return The new created sort object.
      */
     public static Sort of() {
@@ -40,6 +41,7 @@ private Sort() {
 
     /**
      * Use this method to define the order / sorting by the given fields
+     *
      * @param fieldName The field which is used to sort
      * @param ascending The direction of the sorting
      * @return The used Sort object
@@ -52,6 +54,7 @@ public Sort order(String fieldName, boolean ascending) {
     /**
      * Use this method to define the order / sorting by the given fields,
      * but sets the ascending value to "true"
+     *
      * @param fieldName The field which is used to sort
      * @return The used Sort object
      */
@@ -61,6 +64,7 @@ public Sort order(String fieldName) {
 
     /**
      * Use this method to set the limit of entities of the current sorting.
+     *
      * @param limit The amount of the entities in the returned List.
      * @return The used Sort object
      */
@@ -71,6 +75,7 @@ public Sort limit(int limit) {
 
     /**
      * Use this method to set the skipped entities of the current sorting.
+     *
      * @param skip The amount of the entities, which should be skipped, before creating the List.
      * @return The used Sort object
      */

From 93bce409e470755736a804d04c536f7db87dcd86 Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Fri, 27 Jan 2023 19:57:37 +0100
Subject: [PATCH 08/19] Add javadocs to utility classes

---
 .../eu/koboo/en2do/utility/AnnotationUtils.java   | 12 ++++++++++++
 .../java/eu/koboo/en2do/utility/DateUtils.java    |  3 +++
 .../java/eu/koboo/en2do/utility/EntityUtils.java  |  9 +++++++++
 .../java/eu/koboo/en2do/utility/FieldUtils.java   | 15 +++++++++++++++
 .../java/eu/koboo/en2do/utility/GenericUtils.java |  3 +++
 5 files changed, 42 insertions(+)

diff --git a/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java b/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java
index 3046f1a6..347bb8b4 100644
--- a/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java
+++ b/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java
@@ -7,9 +7,21 @@
 import java.util.HashSet;
 import java.util.Set;
 
+/**
+ * A utility class for everything related to annotations
+ */
 @UtilityClass
 public class AnnotationUtils {
 
+    /**
+     * This method is ued to get all annotations from an entity class, using while loop,
+     * to iterate through all super-types.
+     * @param entityClass The class, which should be scanned.
+     * @param annotationClass the searched annotation
+     * @return The Set with all found annotations of type A
+     * @param <E> The generic type of the Class
+     * @param <A> The generic type of the annotation Class
+     */
     public <E, A extends Annotation> Set<A> collectAnnotations(Class<E> entityClass, Class<A> annotationClass) {
         Set<A> annotationSet = new HashSet<>();
         Class<?> clazz = entityClass;
diff --git a/src/main/java/eu/koboo/en2do/utility/DateUtils.java b/src/main/java/eu/koboo/en2do/utility/DateUtils.java
index 2058d787..ddf68576 100644
--- a/src/main/java/eu/koboo/en2do/utility/DateUtils.java
+++ b/src/main/java/eu/koboo/en2do/utility/DateUtils.java
@@ -10,6 +10,9 @@
 import java.util.TimeZone;
 import java.util.concurrent.TimeUnit;
 
+/**
+ * A utility class for working with "java.util.Date".
+ */
 @UtilityClass
 @SuppressWarnings("unused")
 public class DateUtils {
diff --git a/src/main/java/eu/koboo/en2do/utility/EntityUtils.java b/src/main/java/eu/koboo/en2do/utility/EntityUtils.java
index 51e62f3b..e169f2d0 100644
--- a/src/main/java/eu/koboo/en2do/utility/EntityUtils.java
+++ b/src/main/java/eu/koboo/en2do/utility/EntityUtils.java
@@ -10,9 +10,18 @@
 import java.util.Arrays;
 import java.util.List;
 
+/**
+ * A utility class for everything related to entity properties.
+ */
 @UtilityClass
 public class EntityUtils {
 
+    /**
+     * This method is used to copy all field values from one entity to another.
+     * It also works with inheritance.
+     * @param from The entity to copy from
+     * @param to The entity to copy to
+     */
     public void copyProperties(Object from, Object to) {
         Class<?> fromClass = from.getClass();
         Class<?> toClass = to.getClass();
diff --git a/src/main/java/eu/koboo/en2do/utility/FieldUtils.java b/src/main/java/eu/koboo/en2do/utility/FieldUtils.java
index 293c2612..8264bb81 100644
--- a/src/main/java/eu/koboo/en2do/utility/FieldUtils.java
+++ b/src/main/java/eu/koboo/en2do/utility/FieldUtils.java
@@ -7,9 +7,18 @@
 import java.util.HashSet;
 import java.util.Set;
 
+/**
+ * A utility class for everything related to fields.
+ */
 @UtilityClass
 public class FieldUtils {
 
+    /**
+     * This method is used to scan a class for all fields.
+     * @param typeClass The class, which should be scanned
+     * @return The Set with all found fields of the given class.
+     * @param <E> The generic type of the class
+     */
     public <E> Set<Field> collectFields(Class<E> typeClass) {
         Set<Field> fields = new HashSet<>();
         Class<?> clazz = typeClass;
@@ -24,6 +33,12 @@ public <E> Set<Field> collectFields(Class<E> typeClass) {
         return fields;
     }
 
+    /**
+     * This method is used to iterate through a set of fields and search for a field by its name.
+     * @param fieldName The field name, which should be searched.
+     * @param fieldSet The Set, which should be iterated through
+     * @return The field, if found. If not found, it returns "null"
+     */
     public Field findFieldByName(String fieldName, Set<Field> fieldSet) {
         for (Field field : fieldSet) {
             if (!field.getName().equalsIgnoreCase(fieldName)) {
diff --git a/src/main/java/eu/koboo/en2do/utility/GenericUtils.java b/src/main/java/eu/koboo/en2do/utility/GenericUtils.java
index a3f25905..5990d982 100644
--- a/src/main/java/eu/koboo/en2do/utility/GenericUtils.java
+++ b/src/main/java/eu/koboo/en2do/utility/GenericUtils.java
@@ -7,6 +7,9 @@
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 
+/**
+ * A utility class for everything related to generic types or class types.
+ */
 @UtilityClass
 public class GenericUtils {
 

From 12d3c74c16f2bfda66e4d700f0f4d721a0e47cc6 Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Sat, 28 Jan 2023 16:35:52 +0100
Subject: [PATCH 09/19] Rename methods of GenericUtils to better match use-case

---
 src/main/java/eu/koboo/en2do/utility/GenericUtils.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/main/java/eu/koboo/en2do/utility/GenericUtils.java b/src/main/java/eu/koboo/en2do/utility/GenericUtils.java
index 5990d982..da6de4c7 100644
--- a/src/main/java/eu/koboo/en2do/utility/GenericUtils.java
+++ b/src/main/java/eu/koboo/en2do/utility/GenericUtils.java
@@ -13,13 +13,13 @@
 @UtilityClass
 public class GenericUtils {
 
-    public Class<?> getGenericTypeOfReturnList(Method method) {
+    public Class<?> getGenericTypeOfReturnType(Method method) {
         Type returnType = method.getGenericReturnType();
         ParameterizedType type = (ParameterizedType) returnType;
         return (Class<?>) type.getActualTypeArguments()[0];
     }
 
-    public Class<?> getGenericTypeOfParameterList(Method method, int paramIndex) {
+    public Class<?> getGenericTypeOfParameter(Method method, int paramIndex) {
         Parameter parameter = method.getParameters()[paramIndex];
         Type parameterType = parameter.getParameterizedType();
         ParameterizedType type = (ParameterizedType) parameterType;

From 9d3a1e959e9a085d99806539ff37234341554cb1 Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Sat, 28 Jan 2023 17:02:48 +0100
Subject: [PATCH 10/19] Create @Async annotation to mark methods async

---
 .../koboo/en2do/repository/methods/async/Async.java  | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 src/main/java/eu/koboo/en2do/repository/methods/async/Async.java

diff --git a/src/main/java/eu/koboo/en2do/repository/methods/async/Async.java b/src/main/java/eu/koboo/en2do/repository/methods/async/Async.java
new file mode 100644
index 00000000..3cf38163
--- /dev/null
+++ b/src/main/java/eu/koboo/en2do/repository/methods/async/Async.java
@@ -0,0 +1,12 @@
+package eu.koboo.en2do.repository.methods.async;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Async {
+
+}

From 5b0de78e55a2279497adaa4bead3c0fda97ff67d Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Sat, 28 Jan 2023 17:03:06 +0100
Subject: [PATCH 11/19] Update validation for async methods

---
 .../java/eu/koboo/en2do/MongoManager.java     | 34 +++++++++++++++----
 .../MethodInvalidAsyncNameException.java      | 15 ++++++++
 .../MethodInvalidAsyncReturnException.java    | 14 ++++++++
 3 files changed, 57 insertions(+), 6 deletions(-)
 create mode 100644 src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncNameException.java
 create mode 100644 src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncReturnException.java

diff --git a/src/main/java/eu/koboo/en2do/MongoManager.java b/src/main/java/eu/koboo/en2do/MongoManager.java
index 5f414612..7f3dfe71 100644
--- a/src/main/java/eu/koboo/en2do/MongoManager.java
+++ b/src/main/java/eu/koboo/en2do/MongoManager.java
@@ -21,15 +21,14 @@
 import eu.koboo.en2do.internal.methods.operators.FilterOperator;
 import eu.koboo.en2do.internal.methods.operators.MethodOperator;
 import eu.koboo.en2do.internal.methods.predefined.impl.*;
+import eu.koboo.en2do.repository.*;
 import eu.koboo.en2do.repository.Collection;
-import eu.koboo.en2do.repository.DropEntitiesOnStart;
-import eu.koboo.en2do.repository.DropIndexesOnStart;
-import eu.koboo.en2do.repository.Repository;
 import eu.koboo.en2do.repository.entity.Id;
 import eu.koboo.en2do.repository.entity.NonIndex;
 import eu.koboo.en2do.repository.entity.compound.CompoundIndex;
 import eu.koboo.en2do.repository.entity.compound.Index;
 import eu.koboo.en2do.repository.entity.ttl.TTLIndex;
+import eu.koboo.en2do.repository.methods.async.Async;
 import eu.koboo.en2do.repository.methods.pagination.Pagination;
 import eu.koboo.en2do.repository.methods.sort.*;
 import eu.koboo.en2do.repository.methods.transform.Transform;
@@ -50,6 +49,7 @@
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Type;
 import java.util.*;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.regex.Pattern;
 
@@ -238,7 +238,7 @@ public <E, ID, R extends Repository<E, ID>> R create(Class<R> repositoryClass) {
 
             MongoCollection<E> entityCollection = database.getCollection(entityCollectionName, entityClass);
 
-            RepositoryMeta<E, ID, R> repositoryMeta = new RepositoryMeta<>(
+            RepositoryMeta<E, ID, R> repositoryMeta = new RepositoryMeta<>(this,
                     repositoryClass, entityClass,
                     entityFieldSet,
                     entityUniqueIdClass, entityUniqueIdField,
@@ -273,11 +273,13 @@ public <E, ID, R extends Repository<E, ID>> R create(Class<R> repositoryClass) {
             for (Method method : repositoryClass.getMethods()) {
                 String methodName = method.getName();
 
+                // Apply transform annotation
                 Transform transform = method.getAnnotation(Transform.class);
                 if (transform != null) {
                     methodName = transform.value();
                 }
 
+                // Check if we catch a predefined method
                 if (repositoryMeta.isRepositoryMethod(methodName)) {
                     continue;
                 }
@@ -286,9 +288,29 @@ public <E, ID, R extends Repository<E, ID>> R create(Class<R> repositoryClass) {
                 if (IGNORED_DEFAULT_METHODS.contains(methodName)) {
                     continue;
                 }
-                // Check for the return-types of the methods, and their defined names to match our pattern.
+
+                // Get the default return type of the method
                 Class<?> returnType = method.getReturnType();
 
+                // Check if the method is async and if so, check for completable future return type.
+                boolean isAsyncMethod = method.isAnnotationPresent(Async.class);
+                if(isAsyncMethod) {
+                    // Check async method name
+                    if(methodName.startsWith("async")) {
+                        String predefinedName = repositoryMeta.getPredefinedNameByAsyncName(methodName);
+                        if(repositoryMeta.isRepositoryMethod(predefinedName)) {
+                            continue;
+                        }
+                        throw new MethodInvalidAsyncNameException(method, repositoryClass);
+                    }
+                    // Check CompletableFuture return type
+                    if(GenericUtils.isNotTypeOf(returnType, CompletableFuture.class)) {
+                        throw new MethodInvalidAsyncReturnException(method, repositoryClass);
+                    }
+                    returnType = GenericUtils.getGenericTypeOfReturnType(method);
+                }
+
+
                 // Parse the MethodOperator by the methodName
                 MethodOperator methodOperator = MethodOperator.parseMethodStartsWith(methodName);
                 if (methodOperator == null) {
@@ -341,7 +363,7 @@ public <E, ID, R extends Repository<E, ID>> R create(Class<R> repositoryClass) {
                                 if (GenericUtils.isNotTypeOf(List.class, paramClass)) {
                                     throw new MethodMismatchingTypeException(method, repositoryClass, List.class, paramClass);
                                 }
-                                Class<?> listType = GenericUtils.getGenericTypeOfParameterList(method, paramIndex);
+                                Class<?> listType = GenericUtils.getGenericTypeOfParameter(method, paramIndex);
                                 if (GenericUtils.isNotTypeOf(fieldClass, listType)) {
                                     throw new MethodInvalidListParameterException(method, repositoryClass, fieldClass, listType);
                                 }
diff --git a/src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncNameException.java b/src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncNameException.java
new file mode 100644
index 00000000..523f39cc
--- /dev/null
+++ b/src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncNameException.java
@@ -0,0 +1,15 @@
+package eu.koboo.en2do.internal.exception.methods;
+
+import eu.koboo.en2do.repository.methods.async.Async;
+
+import java.lang.reflect.Method;
+
+public class MethodInvalidAsyncNameException extends Exception {
+
+    public MethodInvalidAsyncNameException(Method method, Class<?> repoClass) {
+        super("Methods, which start with the keyword \"async\" are not allowed in repository, except the predefined methods " +
+                "of the repository itself. If you want to create \"async\" methods, just annotate any method with " + Async.class +
+                " and encapsulate the return type in a CompletableFuture<T>. Invalid method is \"" + method.getName() + "\"" +
+                " in repository " + repoClass.getName());
+    }
+}
diff --git a/src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncReturnException.java b/src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncReturnException.java
new file mode 100644
index 00000000..8ecae72d
--- /dev/null
+++ b/src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncReturnException.java
@@ -0,0 +1,14 @@
+package eu.koboo.en2do.internal.exception.methods;
+
+import eu.koboo.en2do.repository.methods.async.Async;
+
+import java.lang.reflect.Method;
+
+public class MethodInvalidAsyncReturnException extends Exception {
+
+    public MethodInvalidAsyncReturnException(Method method, Class<?> repoClass) {
+        super("Methods, which are annotated with " + Async.class + " have to return a CompletableFuture<T> with their " +
+                " encapsulate return type as T. Invalid method is \"" + method.getName() + "\"" +
+                " in repository " + repoClass.getName());
+    }
+}

From 972daba80075634fe550042d5db72c92d998a8a6 Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Sat, 28 Jan 2023 17:04:24 +0100
Subject: [PATCH 12/19] Handle async method invocation

---
 .../koboo/en2do/internal/MethodCallable.java  |  6 +++
 .../internal/RepositoryInvocationHandler.java | 48 +++++++++++++++++--
 .../koboo/en2do/internal/RepositoryMeta.java  | 15 ++++--
 3 files changed, 59 insertions(+), 10 deletions(-)
 create mode 100644 src/main/java/eu/koboo/en2do/internal/MethodCallable.java

diff --git a/src/main/java/eu/koboo/en2do/internal/MethodCallable.java b/src/main/java/eu/koboo/en2do/internal/MethodCallable.java
new file mode 100644
index 00000000..2b81a1bb
--- /dev/null
+++ b/src/main/java/eu/koboo/en2do/internal/MethodCallable.java
@@ -0,0 +1,6 @@
+package eu.koboo.en2do.internal;
+
+public interface MethodCallable {
+
+    Object call() throws Exception;
+}
diff --git a/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java b/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java
index ee0044fb..7632e11a 100644
--- a/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java
+++ b/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java
@@ -3,10 +3,10 @@
 import com.mongodb.client.FindIterable;
 import com.mongodb.client.MongoCollection;
 import eu.koboo.en2do.internal.exception.methods.MethodUnsupportedException;
-import eu.koboo.en2do.internal.exception.repository.RepositoryInvalidCallException;
 import eu.koboo.en2do.internal.methods.dynamic.DynamicMethod;
 import eu.koboo.en2do.internal.methods.predefined.PredefinedMethod;
 import eu.koboo.en2do.repository.Repository;
+import eu.koboo.en2do.repository.methods.async.Async;
 import eu.koboo.en2do.repository.methods.transform.Transform;
 import lombok.AccessLevel;
 import lombok.AllArgsConstructor;
@@ -16,6 +16,7 @@
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.concurrent.CompletableFuture;
 
 @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
 @AllArgsConstructor
@@ -26,12 +27,14 @@ public class RepositoryInvocationHandler<E, ID, R extends Repository<E, ID>> imp
     @Override
     @SuppressWarnings("all")
     public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {
-        String methodName = method.getName();
 
+        // Create value of the final methodName
+        String tempMethodName = method.getName();
         Transform transform = method.getAnnotation(Transform.class);
         if (transform != null) {
-            methodName = transform.value();
+            tempMethodName = transform.value();
         }
+        String methodName = tempMethodName;
 
         // Get and check if a static handler for the methodName is available.
         PredefinedMethod<E, ID, R> methodHandler = repositoryMeta.lookupPredefinedMethod(methodName);
@@ -41,6 +44,19 @@ public Object invoke(Object proxy, Method method, Object[] arguments) throws Thr
         }
         // No static handler found.
 
+        // Check for predefined method with async prefix.
+        boolean isAsyncMethod = method.isAnnotationPresent(Async.class);
+        if (transform == null && isAsyncMethod) {
+            String predefinedName = repositoryMeta.getPredefinedNameByAsyncName(methodName);
+            PredefinedMethod<E, ID, R> methodHandlerFuture = repositoryMeta.lookupPredefinedMethod(predefinedName);
+            if (methodHandlerFuture != null) {
+                // Just handle the arguments and return the object
+                CompletableFuture<Object> future = new CompletableFuture<>();
+                executeFuture(future, () -> methodHandlerFuture.handle(method, arguments));
+                return future;
+            }
+        }
+
         // Get and check if any dynamic method matches the methodName
         DynamicMethod<E, ID, R> dynamicMethod = repositoryMeta.lookupDynamicMethod(methodName);
         if (dynamicMethod == null) {
@@ -48,10 +64,22 @@ public Object invoke(Object proxy, Method method, Object[] arguments) throws Thr
             throw new MethodUnsupportedException(method, repositoryMeta.getRepositoryClass());
         }
 
+        MethodCallable methodCallable = () -> executeMethod(dynamicMethod, arguments, method, methodName);
+        if(isAsyncMethod) {
+            CompletableFuture<Object> future = new CompletableFuture<>();
+            executeFuture(future, methodCallable);
+            return future;
+        } else {
+            return methodCallable.call();
+        }
+    }
+
+    private Object executeMethod(DynamicMethod<E, ID, R> dynamicMethod, Object[] arguments, Method method, String methodName) throws Exception {
         // Generate bson filter by dynamic Method object.
         Bson filter = dynamicMethod.createBsonFilter(arguments);
         // Switch-case the method operator to use the correct mongo query.
         final MongoCollection<E> collection = repositoryMeta.getCollection();
+
         return switch (dynamicMethod.getMethodOperator()) {
             case COUNT -> collection.countDocuments(filter);
             case DELETE -> collection.deleteMany(filter).wasAcknowledged();
@@ -73,8 +101,18 @@ public Object invoke(Object proxy, Method method, Object[] arguments) throws Thr
                 findIterable = repositoryMeta.applyPageObject(method, findIterable, arguments);
                 yield findIterable.into(new ArrayList<>());
             }
-            default -> // Couldn't find any match method operator
-                    throw new RepositoryInvalidCallException(method, repositoryMeta.getRepositoryClass());
+            // Couldn't find any match method operator, but that shouldn't happen
         };
     }
+
+    private void executeFuture(CompletableFuture<Object> future, MethodCallable callable) {
+        //TODO: Check for ExecutorService from manager
+        future.completeAsync(() -> {
+            try {
+                return callable.call();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
+    }
 }
diff --git a/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java b/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java
index 7b1ae8ac..d9a0a4e2 100644
--- a/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java
+++ b/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java
@@ -4,6 +4,7 @@
 import com.mongodb.client.FindIterable;
 import com.mongodb.client.MongoCollection;
 import com.mongodb.client.model.Filters;
+import eu.koboo.en2do.MongoManager;
 import eu.koboo.en2do.internal.exception.methods.MethodInvalidPageException;
 import eu.koboo.en2do.internal.exception.methods.MethodInvalidSortLimitException;
 import eu.koboo.en2do.internal.exception.methods.MethodInvalidSortSkipException;
@@ -24,15 +25,13 @@
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
 @Getter
 public class RepositoryMeta<E, ID, R extends Repository<E, ID>> {
 
+    MongoManager mongoManager;
     String collectionName;
     MongoCollection<E> collection;
 
@@ -54,10 +53,11 @@ public class RepositoryMeta<E, ID, R extends Repository<E, ID>> {
     @Getter(AccessLevel.NONE)
     Map<String, DynamicMethod<E, ID, R>> dynamicMethodRegistry;
 
-    public RepositoryMeta(Class<R> repositoryClass, Class<E> entityClass,
+    public RepositoryMeta(MongoManager mongoManager, Class<R> repositoryClass, Class<E> entityClass,
                           Set<Field> entityFieldSet,
                           Class<ID> entityUniqueIdClass, Field entityUniqueIdField,
                           MongoCollection<E> collection, String collectionName) {
+        this.mongoManager = mongoManager;
         this.collectionName = collectionName;
         this.collection = collection;
 
@@ -254,4 +254,9 @@ public FindIterable<E> applyPageObject(Method method, FindIterable<E> findIterab
         findIterable.allowDiskUse(true);
         return findIterable;
     }
+
+    public String getPredefinedNameByAsyncName(String asyncName) {
+        String predefinedName = asyncName.replaceFirst("async", "");
+        return predefinedName.substring(0, 1).toLowerCase(Locale.ROOT) + predefinedName.substring(1);
+    }
 }

From 8a984155f76ba9ac35026dabb637acfed23e7f8e Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Sat, 28 Jan 2023 17:09:11 +0100
Subject: [PATCH 13/19] Create interface for async repositories

---
 .../en2do/repository/AsyncRepository.java     | 111 ++++++++++++++++++
 1 file changed, 111 insertions(+)
 create mode 100644 src/main/java/eu/koboo/en2do/repository/AsyncRepository.java

diff --git a/src/main/java/eu/koboo/en2do/repository/AsyncRepository.java b/src/main/java/eu/koboo/en2do/repository/AsyncRepository.java
new file mode 100644
index 00000000..a47ef4eb
--- /dev/null
+++ b/src/main/java/eu/koboo/en2do/repository/AsyncRepository.java
@@ -0,0 +1,111 @@
+package eu.koboo.en2do.repository;
+
+import eu.koboo.en2do.repository.methods.async.Async;
+import eu.koboo.en2do.repository.methods.pagination.Pagination;
+import eu.koboo.en2do.repository.methods.sort.Sort;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * The default Repository interface, which predefines several useful methods.
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/methods/predefined-methods">...</a>
+ * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-repository">...</a>
+ *
+ * @param <E>  The generic type of the Entity
+ * @param <ID> The generic type of the field annotated with "@Id" in the Entity
+ */
+@SuppressWarnings("unused")
+public interface AsyncRepository<E, ID> {
+
+    /**
+     * Async representation
+     * @see Repository#countAll()
+     */
+    @Async
+    CompletableFuture<Long> asyncCountAll();
+
+    /**
+     * Async representation
+     * @see Repository#delete(Object)
+     */
+    @Async
+    CompletableFuture<Boolean> asyncDelete(E entity);
+
+    /**
+     * Async representation
+     * @see Repository#deleteAll(List)
+     */
+    @Async
+    CompletableFuture<Boolean> asyncDeleteAll(List<E> entityList);
+
+    /**
+     * Async representation
+     * @see Repository#deleteById(Object)
+     */
+    @Async
+    CompletableFuture<Boolean> asyncDeleteById(ID identifier);
+
+    /**
+     * Async representation
+     * @see Repository#drop()
+     */
+    @Async
+    CompletableFuture<Boolean> asyncDrop();
+
+    /**
+     * Async representation
+     * @see Repository#exists(Object)
+     */
+    @Async
+    CompletableFuture<Boolean> asyncExists(E entity);
+
+    /**
+     * Async representation
+     * @see Repository#existsById(Object)
+     */
+    @Async
+    CompletableFuture<Boolean> asyncExistsById(ID identifier);
+
+    /**
+     * Async representation
+     * @see Repository#findAll()
+     */
+    @Async
+    CompletableFuture<List<E>> asyncFindAll();
+
+    /**
+     * Async representation
+     * @see Repository#findFirstById(Object)
+     */
+    @Async
+    CompletableFuture<E> asyncFindFirstById(ID identifier);
+
+    /**
+     * Async representation
+     * @see Repository#pageAll(Pagination)
+     */
+    @Async
+    CompletableFuture<List<E>> asyncPageAll(Pagination pagination);
+
+    /**
+     * Async representation
+     * @see Repository#save(Object)
+     */
+    @Async
+    CompletableFuture<Boolean> asyncSave(E entity);
+
+    /**
+     * Async representation
+     * @see Repository#saveAll(List)
+     */
+    @Async
+    CompletableFuture<Boolean> asyncSaveAll(List<E> entityList);
+
+    /**
+     * Async representation
+     * @see Repository#sortAll(Sort)
+     */
+    @Async
+    CompletableFuture<List<E>> asyncSortAll(Sort sort);
+}

From cf5c58aa99b88a044f9a1dbdf1a50658f64d2e10 Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Sat, 28 Jan 2023 17:09:27 +0100
Subject: [PATCH 14/19] Refactor changes

---
 .../methods/operators/MethodOperator.java     |  4 +-
 .../CustomerExtendedRepository.java           | 12 ++--
 ...xtendedFindFirstByFirstNameExistsTest.java | 56 +++++++++++++++++++
 3 files changed, 65 insertions(+), 7 deletions(-)
 create mode 100644 src/test/java/eu/koboo/en2do/test/customerextended/tests/CustomerExtendedFindFirstByFirstNameExistsTest.java

diff --git a/src/main/java/eu/koboo/en2do/internal/methods/operators/MethodOperator.java b/src/main/java/eu/koboo/en2do/internal/methods/operators/MethodOperator.java
index 29b171c3..70c98bff 100644
--- a/src/main/java/eu/koboo/en2do/internal/methods/operators/MethodOperator.java
+++ b/src/main/java/eu/koboo/en2do/internal/methods/operators/MethodOperator.java
@@ -23,7 +23,7 @@ public enum MethodOperator {
         if (GenericUtils.isNotTypeOf(List.class, returnType)) {
             throw new MethodFindListReturnTypeException(method, entityClass, repoClass);
         }
-        Class<?> listType = GenericUtils.getGenericTypeOfReturnList(method);
+        Class<?> listType = GenericUtils.getGenericTypeOfReturnType(method);
         if (!listType.isAssignableFrom(entityClass)) {
             throw new MethodFindListTypeException(method, repoClass, listType);
         }
@@ -47,7 +47,7 @@ public enum MethodOperator {
         if (GenericUtils.isNotTypeOf(List.class, returnType)) {
             throw new MethodFindListReturnTypeException(method, entityClass, repoClass);
         }
-        Class<?> listType = GenericUtils.getGenericTypeOfReturnList(method);
+        Class<?> listType = GenericUtils.getGenericTypeOfReturnType(method);
         if (!listType.isAssignableFrom(entityClass)) {
             throw new MethodFindListTypeException(method, repoClass, listType);
         }
diff --git a/src/test/java/eu/koboo/en2do/test/customerextended/CustomerExtendedRepository.java b/src/test/java/eu/koboo/en2do/test/customerextended/CustomerExtendedRepository.java
index dd5571c1..d394955d 100644
--- a/src/test/java/eu/koboo/en2do/test/customerextended/CustomerExtendedRepository.java
+++ b/src/test/java/eu/koboo/en2do/test/customerextended/CustomerExtendedRepository.java
@@ -1,16 +1,18 @@
 package eu.koboo.en2do.test.customerextended;
 
-import eu.koboo.en2do.repository.Collection;
-import eu.koboo.en2do.repository.DropEntitiesOnStart;
-import eu.koboo.en2do.repository.DropIndexesOnStart;
-import eu.koboo.en2do.repository.Repository;
+import eu.koboo.en2do.repository.*;
+import eu.koboo.en2do.repository.methods.async.Async;
 
 import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
 
 @Collection("customer_extended_repository")
 @DropIndexesOnStart
 @DropEntitiesOnStart
-public interface CustomerExtendedRepository extends Repository<CustomerExtended, UUID> {
+public interface CustomerExtendedRepository extends Repository<CustomerExtended, UUID>, AsyncRepository<CustomerExtended, UUID> {
 
     CustomerExtended findFirstByFirstName(String firstName);
+
+    @Async
+    CompletableFuture<CustomerExtended> findFirstByFirstNameExists();
 }
diff --git a/src/test/java/eu/koboo/en2do/test/customerextended/tests/CustomerExtendedFindFirstByFirstNameExistsTest.java b/src/test/java/eu/koboo/en2do/test/customerextended/tests/CustomerExtendedFindFirstByFirstNameExistsTest.java
new file mode 100644
index 00000000..e0859616
--- /dev/null
+++ b/src/test/java/eu/koboo/en2do/test/customerextended/tests/CustomerExtendedFindFirstByFirstNameExistsTest.java
@@ -0,0 +1,56 @@
+package eu.koboo.en2do.test.customerextended.tests;
+
+import eu.koboo.en2do.test.Const;
+import eu.koboo.en2do.test.customer.Customer;
+import eu.koboo.en2do.test.customerextended.CustomerExtended;
+import eu.koboo.en2do.test.customerextended.CustomerExtendedRepositoryTest;
+import eu.koboo.en2do.utility.EntityUtils;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class CustomerExtendedFindFirstByFirstNameExistsTest extends CustomerExtendedRepositoryTest {
+
+    @Test
+    @Order(1)
+    public void cleanUpRepository() {
+        List<CustomerExtended> customerList = repository.findAll();
+        assertNotNull(customerList);
+        assertTrue(customerList.isEmpty());
+    }
+
+    @Test
+    @Order(2)
+    public void saveCustomer() {
+        Customer customer = Const.createNewCustomer();
+        CustomerExtended customerExtended = new CustomerExtended();
+        EntityUtils.copyProperties(customer, customerExtended);
+        customerExtended.setOrderStatus("Ordered");
+        customerExtended.setLockStatus("Not Locked");
+        assertNotNull(customerExtended);
+        repository.asyncSave(customerExtended)
+                .thenAccept(Assertions::assertTrue)
+                .thenAccept(v -> repository.asyncExists(customerExtended).thenAccept(Assertions::assertTrue));
+    }
+
+    @Test
+    @Order(3)
+    public void operationTest() throws Exception {
+        repository.findFirstByFirstNameExists().thenAccept(customer -> {
+            assertNotNull(customer);
+            assertEquals("Ordered", customer.getOrderStatus());
+            assertEquals("Not Locked", customer.getLockStatus());
+            assertEquals(Const.CUSTOMER_ID, customer.getCustomerId());
+            assertEquals(Const.FIRST_NAME, customer.getFirstName());
+            assertEquals(Const.LAST_NAME, customer.getLastName());
+            assertEquals(Const.BIRTHDAY, customer.getBirthday());
+            assertEquals(Const.PHONE_NUMBER, customer.getPhoneNumber());
+            assertEquals(Const.ORDERS.size(), customer.getOrders().size());
+        });
+        Thread.sleep(1000);
+    }
+}

From 66ebd30da360b91ec0ea47455ff1ecdfd50124b3 Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Sat, 28 Jan 2023 17:09:52 +0100
Subject: [PATCH 15/19] Reformat code + Clean up code

---
 src/main/java/eu/koboo/en2do/MongoManager.java      | 12 +++++++-----
 .../en2do/internal/RepositoryInvocationHandler.java |  2 +-
 .../eu/koboo/en2do/repository/AsyncRepository.java  | 13 +++++++++++++
 .../eu/koboo/en2do/utility/AnnotationUtils.java     |  7 ++++---
 .../java/eu/koboo/en2do/utility/EntityUtils.java    |  3 ++-
 .../java/eu/koboo/en2do/utility/FieldUtils.java     |  6 ++++--
 6 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/src/main/java/eu/koboo/en2do/MongoManager.java b/src/main/java/eu/koboo/en2do/MongoManager.java
index 7f3dfe71..a413e21f 100644
--- a/src/main/java/eu/koboo/en2do/MongoManager.java
+++ b/src/main/java/eu/koboo/en2do/MongoManager.java
@@ -21,8 +21,10 @@
 import eu.koboo.en2do.internal.methods.operators.FilterOperator;
 import eu.koboo.en2do.internal.methods.operators.MethodOperator;
 import eu.koboo.en2do.internal.methods.predefined.impl.*;
-import eu.koboo.en2do.repository.*;
 import eu.koboo.en2do.repository.Collection;
+import eu.koboo.en2do.repository.DropEntitiesOnStart;
+import eu.koboo.en2do.repository.DropIndexesOnStart;
+import eu.koboo.en2do.repository.Repository;
 import eu.koboo.en2do.repository.entity.Id;
 import eu.koboo.en2do.repository.entity.NonIndex;
 import eu.koboo.en2do.repository.entity.compound.CompoundIndex;
@@ -294,17 +296,17 @@ public <E, ID, R extends Repository<E, ID>> R create(Class<R> repositoryClass) {
 
                 // Check if the method is async and if so, check for completable future return type.
                 boolean isAsyncMethod = method.isAnnotationPresent(Async.class);
-                if(isAsyncMethod) {
+                if (isAsyncMethod) {
                     // Check async method name
-                    if(methodName.startsWith("async")) {
+                    if (methodName.startsWith("async")) {
                         String predefinedName = repositoryMeta.getPredefinedNameByAsyncName(methodName);
-                        if(repositoryMeta.isRepositoryMethod(predefinedName)) {
+                        if (repositoryMeta.isRepositoryMethod(predefinedName)) {
                             continue;
                         }
                         throw new MethodInvalidAsyncNameException(method, repositoryClass);
                     }
                     // Check CompletableFuture return type
-                    if(GenericUtils.isNotTypeOf(returnType, CompletableFuture.class)) {
+                    if (GenericUtils.isNotTypeOf(returnType, CompletableFuture.class)) {
                         throw new MethodInvalidAsyncReturnException(method, repositoryClass);
                     }
                     returnType = GenericUtils.getGenericTypeOfReturnType(method);
diff --git a/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java b/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java
index 7632e11a..8648c7c9 100644
--- a/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java
+++ b/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java
@@ -65,7 +65,7 @@ public Object invoke(Object proxy, Method method, Object[] arguments) throws Thr
         }
 
         MethodCallable methodCallable = () -> executeMethod(dynamicMethod, arguments, method, methodName);
-        if(isAsyncMethod) {
+        if (isAsyncMethod) {
             CompletableFuture<Object> future = new CompletableFuture<>();
             executeFuture(future, methodCallable);
             return future;
diff --git a/src/main/java/eu/koboo/en2do/repository/AsyncRepository.java b/src/main/java/eu/koboo/en2do/repository/AsyncRepository.java
index a47ef4eb..e75c79d5 100644
--- a/src/main/java/eu/koboo/en2do/repository/AsyncRepository.java
+++ b/src/main/java/eu/koboo/en2do/repository/AsyncRepository.java
@@ -20,6 +20,7 @@ public interface AsyncRepository<E, ID> {
 
     /**
      * Async representation
+     *
      * @see Repository#countAll()
      */
     @Async
@@ -27,6 +28,7 @@ public interface AsyncRepository<E, ID> {
 
     /**
      * Async representation
+     *
      * @see Repository#delete(Object)
      */
     @Async
@@ -34,6 +36,7 @@ public interface AsyncRepository<E, ID> {
 
     /**
      * Async representation
+     *
      * @see Repository#deleteAll(List)
      */
     @Async
@@ -41,6 +44,7 @@ public interface AsyncRepository<E, ID> {
 
     /**
      * Async representation
+     *
      * @see Repository#deleteById(Object)
      */
     @Async
@@ -48,6 +52,7 @@ public interface AsyncRepository<E, ID> {
 
     /**
      * Async representation
+     *
      * @see Repository#drop()
      */
     @Async
@@ -55,6 +60,7 @@ public interface AsyncRepository<E, ID> {
 
     /**
      * Async representation
+     *
      * @see Repository#exists(Object)
      */
     @Async
@@ -62,6 +68,7 @@ public interface AsyncRepository<E, ID> {
 
     /**
      * Async representation
+     *
      * @see Repository#existsById(Object)
      */
     @Async
@@ -69,6 +76,7 @@ public interface AsyncRepository<E, ID> {
 
     /**
      * Async representation
+     *
      * @see Repository#findAll()
      */
     @Async
@@ -76,6 +84,7 @@ public interface AsyncRepository<E, ID> {
 
     /**
      * Async representation
+     *
      * @see Repository#findFirstById(Object)
      */
     @Async
@@ -83,6 +92,7 @@ public interface AsyncRepository<E, ID> {
 
     /**
      * Async representation
+     *
      * @see Repository#pageAll(Pagination)
      */
     @Async
@@ -90,6 +100,7 @@ public interface AsyncRepository<E, ID> {
 
     /**
      * Async representation
+     *
      * @see Repository#save(Object)
      */
     @Async
@@ -97,6 +108,7 @@ public interface AsyncRepository<E, ID> {
 
     /**
      * Async representation
+     *
      * @see Repository#saveAll(List)
      */
     @Async
@@ -104,6 +116,7 @@ public interface AsyncRepository<E, ID> {
 
     /**
      * Async representation
+     *
      * @see Repository#sortAll(Sort)
      */
     @Async
diff --git a/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java b/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java
index 347bb8b4..cc236067 100644
--- a/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java
+++ b/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java
@@ -16,11 +16,12 @@ public class AnnotationUtils {
     /**
      * This method is ued to get all annotations from an entity class, using while loop,
      * to iterate through all super-types.
-     * @param entityClass The class, which should be scanned.
+     *
+     * @param entityClass     The class, which should be scanned.
      * @param annotationClass the searched annotation
+     * @param <E>             The generic type of the Class
+     * @param <A>             The generic type of the annotation Class
      * @return The Set with all found annotations of type A
-     * @param <E> The generic type of the Class
-     * @param <A> The generic type of the annotation Class
      */
     public <E, A extends Annotation> Set<A> collectAnnotations(Class<E> entityClass, Class<A> annotationClass) {
         Set<A> annotationSet = new HashSet<>();
diff --git a/src/main/java/eu/koboo/en2do/utility/EntityUtils.java b/src/main/java/eu/koboo/en2do/utility/EntityUtils.java
index e169f2d0..8ce57946 100644
--- a/src/main/java/eu/koboo/en2do/utility/EntityUtils.java
+++ b/src/main/java/eu/koboo/en2do/utility/EntityUtils.java
@@ -19,8 +19,9 @@ public class EntityUtils {
     /**
      * This method is used to copy all field values from one entity to another.
      * It also works with inheritance.
+     *
      * @param from The entity to copy from
-     * @param to The entity to copy to
+     * @param to   The entity to copy to
      */
     public void copyProperties(Object from, Object to) {
         Class<?> fromClass = from.getClass();
diff --git a/src/main/java/eu/koboo/en2do/utility/FieldUtils.java b/src/main/java/eu/koboo/en2do/utility/FieldUtils.java
index 8264bb81..a91f7d39 100644
--- a/src/main/java/eu/koboo/en2do/utility/FieldUtils.java
+++ b/src/main/java/eu/koboo/en2do/utility/FieldUtils.java
@@ -15,9 +15,10 @@ public class FieldUtils {
 
     /**
      * This method is used to scan a class for all fields.
+     *
      * @param typeClass The class, which should be scanned
+     * @param <E>       The generic type of the class
      * @return The Set with all found fields of the given class.
-     * @param <E> The generic type of the class
      */
     public <E> Set<Field> collectFields(Class<E> typeClass) {
         Set<Field> fields = new HashSet<>();
@@ -35,8 +36,9 @@ public <E> Set<Field> collectFields(Class<E> typeClass) {
 
     /**
      * This method is used to iterate through a set of fields and search for a field by its name.
+     *
      * @param fieldName The field name, which should be searched.
-     * @param fieldSet The Set, which should be iterated through
+     * @param fieldSet  The Set, which should be iterated through
      * @return The field, if found. If not found, it returns "null"
      */
     public Field findFieldByName(String fieldName, Set<Field> fieldSet) {

From e206f32dfab7f58b467ee5dc4581ead47326712c Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Sat, 28 Jan 2023 20:48:25 +0100
Subject: [PATCH 16/19] Add javadocs see to codec classes

---
 .../codec/InternalPropertyCodecProvider.java     |  7 +++++++
 .../en2do/internal/codec/lang/ClassCodec.java    |  3 +--
 .../internal/codec/map/GenericMapCodec.java      | 16 ++++++++++++++++
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java b/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java
index 814ca85d..bef2a25d 100644
--- a/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java
+++ b/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java
@@ -16,6 +16,13 @@
 @Log
 public class InternalPropertyCodecProvider implements PropertyCodecProvider {
 
+    /**
+     * @see PropertyCodecProvider
+     * @param type the class and bound type parameters for which to get a Codec
+     * @param registry the registry to use for resolving dependent Codec instances
+     * @return The codec from the type
+     * @param <T> The type of the codec
+     */
     @Override
     @SuppressWarnings({"rawtypes", "unchecked"})
     public <T> Codec<T> get(TypeWithTypeParameters<T> type, PropertyCodecRegistry registry) {
diff --git a/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java b/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java
index 9a1b971e..400aebdd 100644
--- a/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java
+++ b/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java
@@ -43,8 +43,7 @@ public Class decode(BsonReader reader, DecoderContext decoderContext) {
     }
 
     /**
-     * See org.bson.codecs.Encoder
-     *
+     * @see org.bson.codecs.Encoder
      * @return the class of the encoded class
      */
     @Override
diff --git a/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java b/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java
index f331dff9..950878cb 100644
--- a/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java
+++ b/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java
@@ -40,6 +40,12 @@ public GenericMapCodec(Class<Map<K, T>> encoderClass, Codec<K> keyCodec, Codec<T
         this.valueCodec = valueCodec;
     }
 
+    /**
+     * @see org.bson.codecs.Encoder
+     * @param writer the BSON writer to encode into
+     * @param map the value to encode
+     * @param encoderContext the encoder context
+     */
     @Override
     public void encode(BsonWriter writer, Map<K, T> map, EncoderContext encoderContext) {
         try (BsonDocumentWriter documentWriter = new BsonDocumentWriter(new BsonDocument())) {
@@ -70,6 +76,12 @@ public void encode(BsonWriter writer, Map<K, T> map, EncoderContext encoderConte
         writer.writeEndDocument();
     }
 
+    /**
+     * @see org.bson.codecs.Decoder
+     * @param reader         the BSON reader
+     * @param context the decoder context
+     * @return The decoded map instance
+     */
     @Override
     @SuppressWarnings("unchecked")
     public Map<K, T> decode(BsonReader reader, DecoderContext context) {
@@ -97,6 +109,10 @@ public Map<K, T> decode(BsonReader reader, DecoderContext context) {
         return map;
     }
 
+    /**
+     * Used to get a new instance of the saved map
+     * @return The new created map instance
+     */
     private Map<K, T> getInstance() {
         if (encoderClass.isInterface()) {
             return new HashMap<>();

From b04d0adc086080dfc7ada874f535131a71fa9647 Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Sat, 28 Jan 2023 21:48:15 +0100
Subject: [PATCH 17/19] Add parameter to MongoManager to allow custom
 ExecutorServices

---
 .../java/eu/koboo/en2do/MongoManager.java     | 26 ++++++++++++++++---
 .../internal/RepositoryInvocationHandler.java |  5 ++--
 .../koboo/en2do/internal/RepositoryMeta.java  |  5 +---
 3 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/src/main/java/eu/koboo/en2do/MongoManager.java b/src/main/java/eu/koboo/en2do/MongoManager.java
index a413e21f..f5de32a2 100644
--- a/src/main/java/eu/koboo/en2do/MongoManager.java
+++ b/src/main/java/eu/koboo/en2do/MongoManager.java
@@ -53,6 +53,7 @@
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
 import java.util.regex.Pattern;
 
 import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
@@ -65,6 +66,7 @@
  * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-mongomanager">...</a>
  */
 @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
+@SuppressWarnings("unused")
 public class MongoManager {
 
     // Predefined methods by Java objects
@@ -76,15 +78,19 @@ public class MongoManager {
     Map<Class<?>, Repository<?, ?>> repositoryRegistry;
     Map<Class<?>, RepositoryMeta<?, ?, ?>> repositoryMetaRegistry;
 
+    ExecutorService executorService;
+
     @Getter
     CodecRegistry codecRegistry;
     MongoClient client;
     MongoDatabase database;
 
-    public MongoManager(Credentials credentials) {
+    public MongoManager(Credentials credentials, ExecutorService executorService) {
         repositoryRegistry = new ConcurrentHashMap<>();
         repositoryMetaRegistry = new ConcurrentHashMap<>();
 
+        this.executorService = executorService;
+
         // If no credentials given, try loading them from default file.
         if (credentials == null) {
             credentials = Credentials.fromFile();
@@ -139,12 +145,24 @@ public MongoManager(Credentials credentials) {
         database = client.getDatabase(databaseString);
     }
 
+    public MongoManager(Credentials credentials) {
+        this(credentials, null);
+    }
+
     public MongoManager() {
-        this(null);
+        this(null, null);
     }
 
+
     public boolean close() {
+        return close(true);
+    }
+
+    public boolean close(boolean shutdownExecutor) {
         try {
+            if(executorService != null && shutdownExecutor) {
+                executorService.shutdown();
+            }
             if (repositoryRegistry != null) {
                 repositoryRegistry.clear();
             }
@@ -240,7 +258,7 @@ public <E, ID, R extends Repository<E, ID>> R create(Class<R> repositoryClass) {
 
             MongoCollection<E> entityCollection = database.getCollection(entityCollectionName, entityClass);
 
-            RepositoryMeta<E, ID, R> repositoryMeta = new RepositoryMeta<>(this,
+            RepositoryMeta<E, ID, R> repositoryMeta = new RepositoryMeta<>(
                     repositoryClass, entityClass,
                     entityFieldSet,
                     entityUniqueIdClass, entityUniqueIdField,
@@ -529,7 +547,7 @@ public <E, ID, R extends Repository<E, ID>> R create(Class<R> repositoryClass) {
             ClassLoader repoClassLoader = repositoryClass.getClassLoader();
             Class<?>[] interfaces = new Class[]{repositoryClass};
             Repository<E, ID> repository = (Repository<E, ID>) Proxy.newProxyInstance(repoClassLoader, interfaces,
-                    new RepositoryInvocationHandler<>(repositoryMeta));
+                    new RepositoryInvocationHandler<>(repositoryMeta, executorService));
             repositoryRegistry.put(repositoryClass, repository);
             repositoryMetaRegistry.put(repositoryClass, repositoryMeta);
             return (R) repository;
diff --git a/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java b/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java
index 8648c7c9..8735ec3b 100644
--- a/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java
+++ b/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java
@@ -17,12 +17,14 @@
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
 
 @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
 @AllArgsConstructor
 public class RepositoryInvocationHandler<E, ID, R extends Repository<E, ID>> implements InvocationHandler {
 
     RepositoryMeta<E, ID, R> repositoryMeta;
+    ExecutorService executorService;
 
     @Override
     @SuppressWarnings("all")
@@ -106,13 +108,12 @@ private Object executeMethod(DynamicMethod<E, ID, R> dynamicMethod, Object[] arg
     }
 
     private void executeFuture(CompletableFuture<Object> future, MethodCallable callable) {
-        //TODO: Check for ExecutorService from manager
         future.completeAsync(() -> {
             try {
                 return callable.call();
             } catch (Exception e) {
                 throw new RuntimeException(e);
             }
-        });
+        }, executorService == null ? future.defaultExecutor() : executorService);
     }
 }
diff --git a/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java b/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java
index d9a0a4e2..f8c368d9 100644
--- a/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java
+++ b/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java
@@ -4,7 +4,6 @@
 import com.mongodb.client.FindIterable;
 import com.mongodb.client.MongoCollection;
 import com.mongodb.client.model.Filters;
-import eu.koboo.en2do.MongoManager;
 import eu.koboo.en2do.internal.exception.methods.MethodInvalidPageException;
 import eu.koboo.en2do.internal.exception.methods.MethodInvalidSortLimitException;
 import eu.koboo.en2do.internal.exception.methods.MethodInvalidSortSkipException;
@@ -31,7 +30,6 @@
 @Getter
 public class RepositoryMeta<E, ID, R extends Repository<E, ID>> {
 
-    MongoManager mongoManager;
     String collectionName;
     MongoCollection<E> collection;
 
@@ -53,11 +51,10 @@ public class RepositoryMeta<E, ID, R extends Repository<E, ID>> {
     @Getter(AccessLevel.NONE)
     Map<String, DynamicMethod<E, ID, R>> dynamicMethodRegistry;
 
-    public RepositoryMeta(MongoManager mongoManager, Class<R> repositoryClass, Class<E> entityClass,
+    public RepositoryMeta(Class<R> repositoryClass, Class<E> entityClass,
                           Set<Field> entityFieldSet,
                           Class<ID> entityUniqueIdClass, Field entityUniqueIdField,
                           MongoCollection<E> collection, String collectionName) {
-        this.mongoManager = mongoManager;
         this.collectionName = collectionName;
         this.collection = collection;
 

From 20dd0c78e3225af6a7e9541e40987270ac37d395 Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Sun, 29 Jan 2023 01:56:45 +0100
Subject: [PATCH 18/19] Fix validator issues

---
 src/main/java/eu/koboo/en2do/internal/Validator.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/eu/koboo/en2do/internal/Validator.java b/src/main/java/eu/koboo/en2do/internal/Validator.java
index 973b8a1d..9c1c24ba 100644
--- a/src/main/java/eu/koboo/en2do/internal/Validator.java
+++ b/src/main/java/eu/koboo/en2do/internal/Validator.java
@@ -86,7 +86,7 @@ public static <E, ID, R extends Repository<E, ID>> void validateCompatibility(
                         .findFirst()
                         .orElse(null);
                 if (field == null) {
-                    throw new RepositoryDescriptorException(typeClass, repositoryClass, descriptor.getName());
+                    continue;
                 }
 
                 // Ignore all fields annotated with transient, because pojo doesn't touch that.

From d5fbbff368e6ffd432478f78531527eba5d56e49 Mon Sep 17 00:00:00 2001
From: Koboo <14143908+Koboo@users.noreply.github.com>
Date: Sun, 29 Jan 2023 01:58:13 +0100
Subject: [PATCH 19/19] Update version to 2.2.0

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 72a63d81..6313ad35 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,6 +1,6 @@
 ### Project properties ###
 projectGroup=eu.koboo
-projectVersion=2.1.0
+projectVersion=2.2.0
 #
 ### Dependency versions ###
 lombokVersion=1.18.24