fix(db): application-assigned ids for entities lacking auto-increment on PostgreSQL-compatible dialects

Eight entities (fact, fact contradiction, morning-card seen, wiki hot
cache / relation / transformation / transformation run / image caption
cache) declared IdType.AUTO while their PostgreSQL-compatible migrations
define the primary key as a plain BIGINT with no identity default.
MyBatis-Plus omits the id column from the generated INSERT under AUTO,
so every insert fails with a NOT NULL violation on those databases —
silently on paths that only log a warning. Switch them to snowflake
ASSIGN_ID, which works on all dialects since auto-increment columns
accept explicit values. Add a parameterized contract test pinning the
id strategy for all eight entities.
This commit is contained in:
matevip 2026-07-15 14:26:47 +08:00
parent 6aad9fd945
commit e2c3cfd5b4
9 changed files with 57 additions and 8 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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. */

View File

@ -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;

View File

@ -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;
/**

View File

@ -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;

View File

@ -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");
}
}