From c3e5f19cb38a02d72c4f4b45c1926033545b7152 Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 11 Nov 2026 10:57:52 +0900 Subject: [PATCH] =?UTF-8?q?fix(subtitle):=20S3=20=EC=BB=AC=EB=9F=BC?= =?UTF-8?q?=EB=AA=85=EC=9D=84=20=EA=B8=B0=EC=A1=B4=20=EC=8A=A4=ED=82=A4?= =?UTF-8?q?=EB=A7=88=EC=99=80=20=EC=9D=BC=EC=B9=98=EC=8B=9C=ED=82=A8?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../subtitle/adapter/persistence/Subtitle.kt | 4 +- .../subtitle/SubtitleSchemaValidationTest.kt | 85 +++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 src/test/kotlin/kr/co/vividnext/sodalive/v2/subtitle/SubtitleSchemaValidationTest.kt diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/v2/subtitle/adapter/persistence/Subtitle.kt b/src/main/kotlin/kr/co/vividnext/sodalive/v2/subtitle/adapter/persistence/Subtitle.kt index e9fdac98..15747a11 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/v2/subtitle/adapter/persistence/Subtitle.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/v2/subtitle/adapter/persistence/Subtitle.kt @@ -17,9 +17,9 @@ class Subtitle( val language: String, @Column(nullable = false, length = 16) val format: String, - @Column(nullable = false, length = 255) + @Column(name = "s3_bucket", nullable = false, length = 255) val s3Bucket: String, - @Column(nullable = false, length = 255) + @Column(name = "s3_key", nullable = false, length = 255) val s3Key: String ) { @Id diff --git a/src/test/kotlin/kr/co/vividnext/sodalive/v2/subtitle/SubtitleSchemaValidationTest.kt b/src/test/kotlin/kr/co/vividnext/sodalive/v2/subtitle/SubtitleSchemaValidationTest.kt new file mode 100644 index 00000000..0874cb41 --- /dev/null +++ b/src/test/kotlin/kr/co/vividnext/sodalive/v2/subtitle/SubtitleSchemaValidationTest.kt @@ -0,0 +1,85 @@ +package kr.co.vividnext.sodalive.v2.subtitle + +import kr.co.vividnext.sodalive.v2.subtitle.adapter.persistence.Subtitle +import org.hibernate.boot.MetadataSources +import org.hibernate.boot.registry.StandardServiceRegistryBuilder +import org.hibernate.cfg.AvailableSettings +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties +import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings +import java.sql.DriverManager +import java.util.UUID + +class SubtitleSchemaValidationTest { + @Test + @DisplayName("기존 DDL의 s3_bucket과 s3_key를 실제 Hibernate validate 및 저장 조회에 사용한다") + fun shouldValidateAndUseExistingS3Columns() { + val url = "jdbc:h2:mem:subtitle-schema-${UUID.randomUUID()};MODE=MySQL" + DriverManager.getConnection(url, "sa", "").use { connection -> + connection.createStatement().use { + it.execute( + """ + CREATE TABLE subtitle ( + id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + job_id VARCHAR(36) NOT NULL, + language VARCHAR(35) NOT NULL, + format VARCHAR(16) NOT NULL, + s3_bucket VARCHAR(255) NOT NULL, + s3_key VARCHAR(255) NOT NULL, + UNIQUE (job_id, language) + ) + """.trimIndent() + ) + } + val bootProperties = HibernateProperties().determineHibernateProperties(emptyMap(), HibernateSettings()) + val registry = StandardServiceRegistryBuilder() + .applySettings(bootProperties) + .applySetting(AvailableSettings.DRIVER, "org.h2.Driver") + .applySetting(AvailableSettings.URL, url) + .applySetting(AvailableSettings.USER, "sa") + .applySetting(AvailableSettings.PASS, "") + .applySetting(AvailableSettings.DIALECT, "org.hibernate.dialect.H2Dialect") + .applySetting(AvailableSettings.HBM2DDL_AUTO, "validate") + .build() + try { + MetadataSources(registry).addAnnotatedClass(Subtitle::class.java) + .buildMetadata().buildSessionFactory().use { factory -> + val id = factory.openSession().use { session -> + val transaction = session.beginTransaction() + val subtitle = Subtitle( + jobId = "550e8400-e29b-41d4-a716-446655440000", + language = "ko-KR", + format = "SRT", + s3Bucket = "subtitle-media", + s3Key = "subtitles/100/550e8400-e29b-41d4-a716-446655440000/ko.srt" + ) + session.persist(subtitle) + transaction.commit() + requireNotNull(subtitle.id) + } + factory.openSession().use { session -> + val stored = session.find(Subtitle::class.java, id) + assertEquals("subtitle-media", stored.s3Bucket) + assertEquals("subtitles/100/550e8400-e29b-41d4-a716-446655440000/ko.srt", stored.s3Key) + } + connection.prepareStatement("SELECT s3_bucket, s3_key FROM subtitle WHERE id = ?").use { + it.setLong(1, id) + it.executeQuery().use { result -> + assertTrue(result.next()) + assertEquals("subtitle-media", result.getString("s3_bucket")) + assertEquals( + "subtitles/100/550e8400-e29b-41d4-a716-446655440000/ko.srt", + result.getString("s3_key") + ) + } + } + } + } finally { + StandardServiceRegistryBuilder.destroy(registry) + } + } + } +}