diff --git a/mateclaw-server/src/main/java/vip/mate/memory/fact/model/FactContradictionEntity.java b/mateclaw-server/src/main/java/vip/mate/memory/fact/model/FactContradictionEntity.java index b2e8b6c0..0a12ee29 100644 --- a/mateclaw-server/src/main/java/vip/mate/memory/fact/model/FactContradictionEntity.java +++ b/mateclaw-server/src/main/java/vip/mate/memory/fact/model/FactContradictionEntity.java @@ -14,7 +14,7 @@ import java.time.LocalDateTime; @TableName("mate_fact_contradiction") public class FactContradictionEntity { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; private Long agentId; diff --git a/mateclaw-server/src/main/java/vip/mate/memory/fact/model/FactEntity.java b/mateclaw-server/src/main/java/vip/mate/memory/fact/model/FactEntity.java index 0fb38a1e..6ed22308 100644 --- a/mateclaw-server/src/main/java/vip/mate/memory/fact/model/FactEntity.java +++ b/mateclaw-server/src/main/java/vip/mate/memory/fact/model/FactEntity.java @@ -17,7 +17,7 @@ import java.time.LocalDateTime; @TableName("mate_fact") public class FactEntity { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; private Long agentId; diff --git a/mateclaw-server/src/main/java/vip/mate/memory/model/MorningCardSeenEntity.java b/mateclaw-server/src/main/java/vip/mate/memory/model/MorningCardSeenEntity.java index df388dfe..62ad1c24 100644 --- a/mateclaw-server/src/main/java/vip/mate/memory/model/MorningCardSeenEntity.java +++ b/mateclaw-server/src/main/java/vip/mate/memory/model/MorningCardSeenEntity.java @@ -14,7 +14,7 @@ import java.time.LocalDateTime; @TableName("mate_morning_card_seen") public class MorningCardSeenEntity { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; private Long userId; diff --git a/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiHotCacheEntity.java b/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiHotCacheEntity.java index d3ff6b3a..73f9d617 100644 --- a/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiHotCacheEntity.java +++ b/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiHotCacheEntity.java @@ -21,7 +21,7 @@ import java.time.LocalDateTime; @TableName("mate_wiki_hot_cache") public class WikiHotCacheEntity { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; private Long kbId; diff --git a/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiImageCaptionCacheEntity.java b/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiImageCaptionCacheEntity.java index 02a4ebc8..d3126d8f 100644 --- a/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiImageCaptionCacheEntity.java +++ b/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiImageCaptionCacheEntity.java @@ -23,7 +23,7 @@ import java.time.LocalDateTime; @TableName("mate_wiki_image_caption_cache") public class WikiImageCaptionCacheEntity { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; /** SHA-256 hex digest (64 chars, lowercase) of the original image bytes. */ diff --git a/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiRelationEntity.java b/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiRelationEntity.java index 59d98310..1e0b7597 100644 --- a/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiRelationEntity.java +++ b/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiRelationEntity.java @@ -29,7 +29,7 @@ import java.time.LocalDateTime; @TableName("mate_wiki_relation") public class WikiRelationEntity { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; private Long kbId; diff --git a/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiTransformationEntity.java b/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiTransformationEntity.java index 75a35914..ebb7af21 100644 --- a/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiTransformationEntity.java +++ b/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiTransformationEntity.java @@ -22,7 +22,7 @@ import java.time.LocalDateTime; @TableName("mate_wiki_transformation") public class WikiTransformationEntity { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; /** diff --git a/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiTransformationRunEntity.java b/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiTransformationRunEntity.java index 2f7dc63b..d3401ec8 100644 --- a/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiTransformationRunEntity.java +++ b/mateclaw-server/src/main/java/vip/mate/wiki/model/WikiTransformationRunEntity.java @@ -19,7 +19,7 @@ import java.time.LocalDateTime; @TableName("mate_wiki_transformation_run") public class WikiTransformationRunEntity { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; private Long transformationId; diff --git a/mateclaw-server/src/test/java/vip/mate/architecture/AutoIncrementFreePrimaryKeyTest.java b/mateclaw-server/src/test/java/vip/mate/architecture/AutoIncrementFreePrimaryKeyTest.java new file mode 100644 index 00000000..8947685b --- /dev/null +++ b/mateclaw-server/src/test/java/vip/mate/architecture/AutoIncrementFreePrimaryKeyTest.java @@ -0,0 +1,49 @@ +package vip.mate.architecture; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import vip.mate.memory.fact.model.FactContradictionEntity; +import vip.mate.memory.fact.model.FactEntity; +import vip.mate.memory.model.MorningCardSeenEntity; +import vip.mate.wiki.model.WikiHotCacheEntity; +import vip.mate.wiki.model.WikiImageCaptionCacheEntity; +import vip.mate.wiki.model.WikiRelationEntity; +import vip.mate.wiki.model.WikiTransformationEntity; +import vip.mate.wiki.model.WikiTransformationRunEntity; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Contract test: these entities are backed by tables whose PostgreSQL-compatible + * dialect defines the primary key as a plain BIGINT without an identity/sequence + * default. {@code IdType.AUTO} makes MyBatis-Plus omit the id column from the + * generated INSERT and rely on database-generated keys, which violates the + * NOT NULL constraint on those databases. Application-assigned snowflake ids + * ({@code IdType.ASSIGN_ID}) work across every supported dialect, since + * auto-increment columns also accept explicit values. + */ +class AutoIncrementFreePrimaryKeyTest { + + @ParameterizedTest + @ValueSource(classes = { + FactEntity.class, + FactContradictionEntity.class, + MorningCardSeenEntity.class, + WikiHotCacheEntity.class, + WikiRelationEntity.class, + WikiTransformationEntity.class, + WikiTransformationRunEntity.class, + WikiImageCaptionCacheEntity.class + }) + void primaryKeyUsesApplicationAssignedId(Class entityClass) throws NoSuchFieldException { + TableId tableId = entityClass.getDeclaredField("id").getAnnotation(TableId.class); + + assertNotNull(tableId, entityClass.getSimpleName() + ".id must be annotated with @TableId"); + assertEquals(IdType.ASSIGN_ID, tableId.type(), + entityClass.getSimpleName() + " must use application-assigned ids: its primary key" + + " column has no auto-increment default on PostgreSQL-compatible databases"); + } +}