Files
llm-wiki/raw/errors/spring-jpa-postgres-lob-oid-cast-2026-06-23.md

3.4 KiB

title, source_type, status, branch, related_projects, tags, created, updated
title source_type status branch related_projects tags created updated
error / spring-jpa-postgres-lob-oid-cast-2026-06-23 error-note raw feature-build-release-supply-chain-contract
ca-skeleton
error
spring-boot
hibernate
jpa
postgresql
lob
oid
2026-06-23 2026-06-23

PostgreSQL column cannot be cast automatically to type oid during Hibernate ddl-auto update

Parent

Symptoms

During application boot, Hibernate threw a warning/exception when trying to run auto-DDL commands:

2026-06-23 14:32:01.573 WARN  [main] o.h.t.s.i.ExceptionHandlerLoggedImpl - GenerationTarget encountered exception accepting command : Error executing DDL "alter table if exists outbox_event alter column payload set data type oid" via JDBC [ERROR: column "payload" cannot be cast automatically to type oid
  Hint: You might need to specify "USING payload::oid".]
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table if exists outbox_event alter column payload set data type oid" via JDBC [ERROR: column "payload" cannot be cast automatically to type oid
  Hint: You might need to specify "USING payload::oid".]

Root Cause

  1. The Flyway migration script V3__outbox_event.sql defines the payload column as text:
    payload          text         NOT NULL,
    
  2. The Java entity OutboxEventEntity.java declared the property using @Lob:
    @Lob
    @Column(name = "payload", nullable = false, updatable = false)
    private String payload;
    
  3. In Hibernate (especially when using a PostgreSQL dialect), a @Lob annotation on a String property maps it to the JDBC type Types.BLOB/CLOB, which in PostgreSQL defaults to the oid (Object Identifier) type rather than standard text.
  4. When ddl-auto is set to update (typical in dev/local environments), Hibernate compares its internal mapping (oid) with the actual DB column type (text). Finding a mismatch, it generates an alter-table command to change the data type to oid.
  5. PostgreSQL rejects this conversion implicitly because converting a text column to oid requires a custom cast expression (USING payload::oid).

Solution

Remove the @Lob annotation from payload in OutboxEventEntity.java and map it using a portable long varchar hint instead of an RDBMS-specific column definition:

@JdbcTypeCode(SqlTypes.LONGVARCHAR)
@Column(name = "payload", nullable = false, updatable = false)
private String payload;

Why it works

  • @JdbcTypeCode(SqlTypes.LONGVARCHAR) maps the String property to standard JDBC LONGVARCHAR type.
  • On PostgreSQL, the Hibernate dialect translates LONGVARCHAR to text.
  • On other databases (like Oracle or H2), it maps to clob or varchar with maximum capacity, preserving vendor-neutrality.
  • Because both Flyway and Hibernate now agree that the column type is text, no DDL alterations are triggered during startup.

Verification & Outcomes

Local Verification

  1. Replaced the annotation in OutboxEventEntity.java.
  2. Ran ./gradlew clean to ensure all stale compilation caches are invalidated.
  3. 기동 검증: ./gradlew :app-bootstrap:bootRun 실행 결과, DDL alteration 경고 및 오류 없이 완전히 깨끗하게 기동되었습니다:
    2026-06-23 14:41:40.748 INFO  [main] d.c.bootstrap.CaSkeletonApplication - Started CaSkeletonApplication in 4.193 seconds