From 7d42d621e946c34afae84bde928ea298174ec03b Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Tue, 16 Dec 2025 21:57:57 +0700 Subject: [PATCH] fix(mongo): codec --- .../storescraperbot/model/AbstractModel.java | 19 ++++++------ .../miti99/storescraperbot/model/Admin.java | 2 +- .../storescraperbot/model/AppleApp.java | 2 +- .../storescraperbot/model/GoogleApp.java | 2 +- .../miti99/storescraperbot/model/Group.java | 2 +- .../AbstractCollectionRepository.java | 2 +- .../repository/AbstractRepository.java | 30 +++++++++++++------ .../AbstractSingletonRepository.java | 2 +- 8 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/miti99/storescraperbot/model/AbstractModel.java b/src/main/java/com/miti99/storescraperbot/model/AbstractModel.java index 8c7eef5..1b816af 100644 --- a/src/main/java/com/miti99/storescraperbot/model/AbstractModel.java +++ b/src/main/java/com/miti99/storescraperbot/model/AbstractModel.java @@ -1,22 +1,21 @@ package com.miti99.storescraperbot.model; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; +import com.google.gson.annotations.SerializedName; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -/** - * Con của AbstractModel phải có getter, setter & field không được final thì mới deserialize được - */ @Getter @NoArgsConstructor @Setter -public abstract class AbstractModel { - @JsonSetter(nulls = Nulls.SKIP) - protected K key; +public abstract class AbstractModel { + @SerializedName("_id") + protected String id; - @JsonProperty("class") + @SerializedName("class") protected String clazz = getClass().getSimpleName(); + + public void setId(Object id) { + this.id = String.valueOf(id); + } } diff --git a/src/main/java/com/miti99/storescraperbot/model/Admin.java b/src/main/java/com/miti99/storescraperbot/model/Admin.java index 83b3c30..17512e2 100644 --- a/src/main/java/com/miti99/storescraperbot/model/Admin.java +++ b/src/main/java/com/miti99/storescraperbot/model/Admin.java @@ -7,6 +7,6 @@ import lombok.Setter; @Getter @Setter -public class Admin extends AbstractModel { +public class Admin extends AbstractModel { Set groups = new HashSet<>(); } diff --git a/src/main/java/com/miti99/storescraperbot/model/AppleApp.java b/src/main/java/com/miti99/storescraperbot/model/AppleApp.java index c58fb6a..6f5b5b2 100644 --- a/src/main/java/com/miti99/storescraperbot/model/AppleApp.java +++ b/src/main/java/com/miti99/storescraperbot/model/AppleApp.java @@ -6,7 +6,7 @@ import lombok.Setter; @Getter @Setter -public class AppleApp extends AbstractModel { +public class AppleApp extends AbstractModel { AppleAppResponse app; long millis; // TODO: handle expire } diff --git a/src/main/java/com/miti99/storescraperbot/model/GoogleApp.java b/src/main/java/com/miti99/storescraperbot/model/GoogleApp.java index 09fc8e8..97473af 100644 --- a/src/main/java/com/miti99/storescraperbot/model/GoogleApp.java +++ b/src/main/java/com/miti99/storescraperbot/model/GoogleApp.java @@ -6,7 +6,7 @@ import lombok.Setter; @Getter @Setter -public class GoogleApp extends AbstractModel { +public class GoogleApp extends AbstractModel { GoogleAppResponse app; long millis; // TODO: handle expire } diff --git a/src/main/java/com/miti99/storescraperbot/model/Group.java b/src/main/java/com/miti99/storescraperbot/model/Group.java index a08b039..fd151e7 100644 --- a/src/main/java/com/miti99/storescraperbot/model/Group.java +++ b/src/main/java/com/miti99/storescraperbot/model/Group.java @@ -9,7 +9,7 @@ import lombok.Setter; @Getter @Setter -public class Group extends AbstractModel { +public class Group extends AbstractModel { List appleApps = new ArrayList<>(); List googleApps = new ArrayList<>(); } diff --git a/src/main/java/com/miti99/storescraperbot/repository/AbstractCollectionRepository.java b/src/main/java/com/miti99/storescraperbot/repository/AbstractCollectionRepository.java index 9887367..53a9dd0 100644 --- a/src/main/java/com/miti99/storescraperbot/repository/AbstractCollectionRepository.java +++ b/src/main/java/com/miti99/storescraperbot/repository/AbstractCollectionRepository.java @@ -8,7 +8,7 @@ import lombok.extern.log4j.Log4j2; * AbstractRepository để các nơi khác gọi */ @Log4j2 -public abstract class AbstractCollectionRepository> +public abstract class AbstractCollectionRepository extends AbstractRepository { @Override diff --git a/src/main/java/com/miti99/storescraperbot/repository/AbstractRepository.java b/src/main/java/com/miti99/storescraperbot/repository/AbstractRepository.java index 60827c8..97de2c2 100644 --- a/src/main/java/com/miti99/storescraperbot/repository/AbstractRepository.java +++ b/src/main/java/com/miti99/storescraperbot/repository/AbstractRepository.java @@ -4,27 +4,31 @@ import static com.miti99.storescraperbot.repository.AbstractSingletonRepository. import com.google.common.base.CaseFormat; import com.miti99.storescraperbot.model.AbstractModel; +import com.miti99.storescraperbot.util.GsonUtil; import com.miti99.storescraperbot.util.MongoDBUtil; import com.mongodb.client.MongoCollection; import com.mongodb.client.model.Filters; import com.mongodb.client.model.ReplaceOptions; import java.lang.reflect.ParameterizedType; import lombok.extern.log4j.Log4j2; +import org.bson.Document; /** * @param class Key * @param class Value */ @Log4j2 -public abstract class AbstractRepository> { +public abstract class AbstractRepository { protected static final String SEPARATOR = "_"; // protected final Class classK = getKeyClass(); protected final Class classV = getDataClass(); protected final String collectionName; + protected final MongoCollection collection; protected AbstractRepository(String collectionName) { this.collectionName = collectionName; MongoDBUtil.createCollectionIfNotExists(collectionName); + collection = MongoDBUtil.DATABASE.getCollection(collectionName, Document.class); } protected AbstractRepository() { @@ -34,6 +38,7 @@ public abstract class AbstractRepository> { "Collection named '%s' is reserved".formatted(COMMON_COLLECTION_NAME)); } MongoDBUtil.createCollectionIfNotExists(collectionName); + collection = MongoDBUtil.DATABASE.getCollection(collectionName, Document.class); } // protected Class getKeyClass() { @@ -52,8 +57,12 @@ public abstract class AbstractRepository> { ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1]; } - protected MongoCollection collection() { - return MongoDBUtil.DATABASE.getCollection(collectionName, classV); + protected String encode(V data) { + return GsonUtil.toJson(data); + } + + protected V decode(String json) { + return GsonUtil.fromJson(json, classV); } protected void init(K key) { @@ -62,7 +71,7 @@ public abstract class AbstractRepository> { return; } V data = classV.getDeclaredConstructor().newInstance(); - data.setKey(key); + data.setId(key); save(key, data); } catch (Exception e) { log.error("Error while initializing data", e); @@ -76,8 +85,9 @@ public abstract class AbstractRepository> { protected void save(K key, V data) { var databaseKey = getDatabaseKey(key); try { - collection() - .replaceOne(Filters.eq("_id", databaseKey), data, new ReplaceOptions().upsert(true)); + var json = encode(data); + var doc = Document.parse(json); + collection.replaceOne(Filters.eq("_id", databaseKey), doc, new ReplaceOptions().upsert(true)); } catch (Exception e) { log.error("save error - key {}, databaseKey {}", key, databaseKey, e); } @@ -86,7 +96,7 @@ public abstract class AbstractRepository> { protected boolean exist(K key) { var databaseKey = getDatabaseKey(key); try { - return collection().countDocuments(Filters.eq("_id", databaseKey)) > 0; + return collection.countDocuments(Filters.eq("_id", databaseKey)) > 0; } catch (Exception e) { log.error("exist error - key {}, databaseKey {}", key, databaseKey, e); return false; @@ -96,7 +106,9 @@ public abstract class AbstractRepository> { protected V load(K key) { var databaseKey = getDatabaseKey(key); try { - return collection().find(Filters.eq("_id", databaseKey)).first(); + var doc = collection.find(Filters.eq("_id", databaseKey)).first(); + if (doc == null) return null; + return decode(doc.toJson()); } catch (Exception e) { log.error("load error - key {}, databaseKey {}", key, databaseKey, e); return null; @@ -106,7 +118,7 @@ public abstract class AbstractRepository> { protected void delete(K key) { var databaseKey = getDatabaseKey(key); try { - collection().deleteOne(Filters.eq("_id", databaseKey)); + collection.deleteOne(Filters.eq("_id", databaseKey)); } catch (Exception e) { log.error("delete error", e); } diff --git a/src/main/java/com/miti99/storescraperbot/repository/AbstractSingletonRepository.java b/src/main/java/com/miti99/storescraperbot/repository/AbstractSingletonRepository.java index 2b2d9df..97cda57 100644 --- a/src/main/java/com/miti99/storescraperbot/repository/AbstractSingletonRepository.java +++ b/src/main/java/com/miti99/storescraperbot/repository/AbstractSingletonRepository.java @@ -8,7 +8,7 @@ import lombok.extern.log4j.Log4j2; * vào. Các repository loại này được lưu trong 1 collection duy nhất là "common" */ @Log4j2 -public abstract class AbstractSingletonRepository> +public abstract class AbstractSingletonRepository extends AbstractRepository { public static final String COMMON_COLLECTION_NAME = "common";