From 4ff2a125c09ac337c9e8fff99424080360419a03 Mon Sep 17 00:00:00 2001 From: rcMarty Date: Fri, 9 Feb 2024 22:04:29 +0100 Subject: [PATCH] Filtering in recursive Initialization Serialization brikule (now i know how to serialize ids instead of fetching) --- .../api/TtsApiApplication.java | 1 + .../IncludeNullOrEmptySerializer.java | 30 +++++++++++++ .../api/rest/jsonfilter/LazyFieldsFilter.java | 15 ++++++- .../api/table/action/Action.java | 7 ++- .../api/table/action/summon/Summon.java | 3 ++ .../api/table/action/summon/SummonAction.java | 17 ++++--- .../api/util/reflect/Initialization.java | 45 +++++++++++++++---- 7 files changed, 100 insertions(+), 18 deletions(-) create mode 100644 src/main/java/cz/trailsthroughshadows/api/rest/jsonfilter/IncludeNullOrEmptySerializer.java diff --git a/src/main/java/cz/trailsthroughshadows/api/TtsApiApplication.java b/src/main/java/cz/trailsthroughshadows/api/TtsApiApplication.java index 27f8a96..c94eebc 100644 --- a/src/main/java/cz/trailsthroughshadows/api/TtsApiApplication.java +++ b/src/main/java/cz/trailsthroughshadows/api/TtsApiApplication.java @@ -34,6 +34,7 @@ public static void main(String[] args) { //jdbc:mariadb://49.13.93.112:3306/tts_api SpringApplication app = new SpringApplication(TtsApiApplication.class); + app.setDefaultProperties(env); app.run(args); log.debug("Running with login: " + dotenv.get("DB_USER") + " -> " + dotenv.get("DB_PASSWORD")); diff --git a/src/main/java/cz/trailsthroughshadows/api/rest/jsonfilter/IncludeNullOrEmptySerializer.java b/src/main/java/cz/trailsthroughshadows/api/rest/jsonfilter/IncludeNullOrEmptySerializer.java new file mode 100644 index 0000000..a312790 --- /dev/null +++ b/src/main/java/cz/trailsthroughshadows/api/rest/jsonfilter/IncludeNullOrEmptySerializer.java @@ -0,0 +1,30 @@ +package cz.trailsthroughshadows.api.rest.jsonfilter; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import jakarta.persistence.Persistence; +import org.hibernate.proxy.HibernateProxy; + +import java.io.IOException; +import java.util.Collection; + +public class IncludeNullOrEmptySerializer extends com.fasterxml.jackson.databind.JsonSerializer { + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + if (value == null) { + gen.writeNull(); + } else if (!Persistence.getPersistenceUtil().isLoaded(value)) { + if (value instanceof Collection) { + gen.writeStartArray(); + for (Object o : (Collection) value) { + gen.writeObject(o); + } + gen.writeEndArray(); + } else { + gen.writeObject(((HibernateProxy) value).getHibernateLazyInitializer().getIdentifier()); + } + } else { + gen.writeObject(value); + } + } +} diff --git a/src/main/java/cz/trailsthroughshadows/api/rest/jsonfilter/LazyFieldsFilter.java b/src/main/java/cz/trailsthroughshadows/api/rest/jsonfilter/LazyFieldsFilter.java index c5de0a2..22e1619 100644 --- a/src/main/java/cz/trailsthroughshadows/api/rest/jsonfilter/LazyFieldsFilter.java +++ b/src/main/java/cz/trailsthroughshadows/api/rest/jsonfilter/LazyFieldsFilter.java @@ -1,15 +1,26 @@ package cz.trailsthroughshadows.api.rest.jsonfilter; import jakarta.persistence.Persistence; +import org.hibernate.proxy.HibernateProxy; + +import java.util.Collection; public class LazyFieldsFilter { @Override public boolean equals(Object obj) { if (obj == null) - return true; + return false; + + if (obj instanceof Collection) + return false; + +// if (obj instanceof HibernateProxy) +// return false; - return !Persistence.getPersistenceUtil().isLoaded(obj); + if (Persistence.getPersistenceUtil().isLoaded(obj)) + return false; + return true; } } diff --git a/src/main/java/cz/trailsthroughshadows/api/table/action/Action.java b/src/main/java/cz/trailsthroughshadows/api/table/action/Action.java index cf4b6b9..c88cbf3 100644 --- a/src/main/java/cz/trailsthroughshadows/api/table/action/Action.java +++ b/src/main/java/cz/trailsthroughshadows/api/table/action/Action.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import cz.trailsthroughshadows.api.rest.jsonfilter.IncludeNullOrEmptySerializer; import cz.trailsthroughshadows.api.rest.jsonfilter.LazyFieldsFilter; import cz.trailsthroughshadows.api.table.action.attack.Attack; import cz.trailsthroughshadows.api.table.action.movement.Movement; @@ -15,13 +17,14 @@ import lombok.Setter; import java.io.Serializable; +import java.util.ArrayList; import java.util.List; @Data @Entity @NoArgsConstructor @Table(name = "Action") -@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = LazyFieldsFilter.class) +//@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = LazyFieldsFilter.class) @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) public class Action { @@ -45,6 +48,7 @@ public class Action { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "movement") + @JsonSerialize(using = IncludeNullOrEmptySerializer.class) private Movement movement; @ManyToOne(fetch = FetchType.LAZY) @@ -61,6 +65,7 @@ public class Action { @OneToMany(fetch = FetchType.LAZY) @JoinColumn(name = "idAction") + @JsonSerialize(using = IncludeNullOrEmptySerializer.class) private List summonActions; public enum Discard implements Serializable { diff --git a/src/main/java/cz/trailsthroughshadows/api/table/action/summon/Summon.java b/src/main/java/cz/trailsthroughshadows/api/table/action/summon/Summon.java index 5041efe..dc8707b 100644 --- a/src/main/java/cz/trailsthroughshadows/api/table/action/summon/Summon.java +++ b/src/main/java/cz/trailsthroughshadows/api/table/action/summon/Summon.java @@ -1,5 +1,7 @@ package cz.trailsthroughshadows.api.table.action.summon; +import com.fasterxml.jackson.annotation.JsonInclude; +import cz.trailsthroughshadows.api.rest.jsonfilter.LazyFieldsFilter; import cz.trailsthroughshadows.api.table.action.Action; import cz.trailsthroughshadows.api.table.effect.Effect; import cz.trailsthroughshadows.api.table.effect.foraction.SummonEffect; @@ -16,6 +18,7 @@ @AllArgsConstructor @Entity @Table(name = "Summon") +@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = LazyFieldsFilter.class) public class Summon implements Cloneable { @Id diff --git a/src/main/java/cz/trailsthroughshadows/api/table/action/summon/SummonAction.java b/src/main/java/cz/trailsthroughshadows/api/table/action/summon/SummonAction.java index 135e452..856ed09 100644 --- a/src/main/java/cz/trailsthroughshadows/api/table/action/summon/SummonAction.java +++ b/src/main/java/cz/trailsthroughshadows/api/table/action/summon/SummonAction.java @@ -1,12 +1,16 @@ package cz.trailsthroughshadows.api.table.action.summon; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import cz.trailsthroughshadows.api.rest.jsonfilter.LazyFieldsFilter; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.io.Externalizable; import java.io.Serializable; @Data @@ -14,6 +18,7 @@ @AllArgsConstructor @Entity @Table(name = "SummonAction") +@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = LazyFieldsFilter.class) @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) public class SummonAction { @@ -21,22 +26,22 @@ public class SummonAction { private SummonActionId id; @ManyToOne(fetch = FetchType.LAZY) - @MapsId("summon_id") + @MapsId("idSummon") @JoinColumn(name = "idSummon") private Summon summon; - @Column(name = "idAction", insertable = false, updatable = false) - private int idAction; - @Column private Integer range; @Embeddable + @Data + @NoArgsConstructor + @AllArgsConstructor public static class SummonActionId implements Serializable { @Column(name = "idSummon") - private Integer summon_id; + private Integer idSummon; @Column(name = "idAction") - private Integer action_id; + private Integer idAction; } } diff --git a/src/main/java/cz/trailsthroughshadows/api/util/reflect/Initialization.java b/src/main/java/cz/trailsthroughshadows/api/util/reflect/Initialization.java index 62d93f9..bdc9f98 100644 --- a/src/main/java/cz/trailsthroughshadows/api/util/reflect/Initialization.java +++ b/src/main/java/cz/trailsthroughshadows/api/util/reflect/Initialization.java @@ -7,21 +7,35 @@ import java.lang.reflect.Field; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; @Log4j2 public class Initialization { + /** + * Initializes all fields of the given entity according to filter in recursive way. + * + * @param entity Entity to initialize + * @param filter White list of fields to initialize + */ + public static void hibernateInitializeAll(Object entity, List filter) { + Map visited = new HashMap<>(); + hibernateInitializeAll(entity, visited, filter); + } + /** * Initializes all fields of the given entity in recursive way. + * * @param entity Entity to initialize */ public static void hibernateInitializeAll(Object entity) { + List filter = List.of(); Map visited = new HashMap<>(); - hibernateInitializeAll(entity, visited); + hibernateInitializeAll(entity, visited, filter); } - private static void hibernateInitializeAll(Object entity, Map visited) { + private static void hibernateInitializeAll(Object entity, Map visited, List filter) { if (entity == null || visited.containsKey(entity)) { if ((visited.get(entity) > 10)) @@ -32,24 +46,36 @@ private static void hibernateInitializeAll(Object entity, Map v //log.debug("Initializing object: {}", entity.getClass().getSimpleName()); Hibernate.initialize(entity); - if (entity instanceof HibernateProxy) { - entity = ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation(); - } +// if (entity instanceof HibernateProxy) { +// entity = ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation(); +// } + initializeFields(entity, visited, filter); + } + + private static void initializeFields(Object entity, Map visited, List filter) { for (Field field : entity.getClass().getDeclaredFields()) { field.setAccessible(true); - //log.debug(" Initializing property: {}", field.getName()); + + if (!(filter.contains(field.getName()) || filter.isEmpty())) { + log.debug(" Skipping property: {}", field.getName()); + continue; + } + + log.debug(" Initializing property: {}", field.getName()); + try { Object child = field.get(entity); if (child != null && !isPrimitiveOrWrapper(child.getClass())) { Hibernate.initialize(child); + log.debug(" Initializing item: {}", child.getClass().getSimpleName()); if (child instanceof Collection) { for (Object item : (Collection) child) { - hibernateInitializeAll(item, visited); + hibernateInitializeAll(item, visited, filter); } } else { - hibernateInitializeAll(child, visited); + hibernateInitializeAll(child, visited, filter); } } } catch (IllegalAccessException e) { @@ -59,7 +85,8 @@ private static void hibernateInitializeAll(Object entity, Map v } private static boolean isPrimitiveOrWrapper(Class clazz) { - return clazz.isPrimitive() || clazz.equals(String.class) || clazz.equals(Integer.class) || clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class) || clazz.equals(Character.class) || clazz.equals(Byte.class) || clazz.equals(Short.class) || clazz.equals(Boolean.class); + return clazz.isPrimitive() || clazz.equals(String.class) || clazz.equals(Integer.class) || clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class) || clazz.equals(Character.class) || clazz.equals(Byte.class) || clazz.equals(Short.class) || clazz.equals(Boolean.class) || clazz.isEnum(); + } }