[JPA 3] persistence.xml 설정으로 DDL, DML SQL 파일 자동실행

식빵·2023년 8월 27일
0

JPA 이론 및 실습

목록 보기
17/17
post-thumbnail

JPA 3 기준으로 작성된 글입니다.
jpa 2.2 를 사용하시는 분들은 따로 조사를 하셔야 합니다.

META-INF/persistence.xml 작성법

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence version="3.0" xmlns="https://jakarta.ee/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence
             https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd">

    <!-- reference: https://jakarta.ee/specifications/persistence/3.0/jakarta-persistence-spec-3.0#a12384 -->
    <!-- postgresql db persistence unit -->
    <persistence-unit name="postgresUnit">
        <properties>
           <!-- 일상적으로 사용되는 기본 설정들 -->
           <property name="jakarta.persistence.jdbc.driver" value="org.postgresql.Driver" />
           <property name="jakarta.persistence.jdbc.url"    value="jdbc:postgresql://localhost:10011/postgres" />
           <property name="jakarta.persistence.jdbc.user"   value="postgres" />
           <property name="jakarta.persistence.jdbc.password" value="postgres" />
           <property name="jakarta.persistence.lock.timeout" value="100"/>
           <property name="jakarta.persistence.query.timeout" value="100"/>
           <property name="hibernate.dialect"    value="org.hibernate.dialect.PostgreSQLDialect" />
           <property name="hibernate.default_schema" value="blog"/>
           <property name="hibernate.show_sql"   value="true" />
           <property name="hibernate.format_sql" value="true" />
           <property name="hibernate.use_sql_comments" value="true" />
           <property name="hibernate.physical_naming_strategy" value="org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy"/>
           <property name="hibernate.jdbc.batch_size" value="10"/>
   
          
           <!-- *************************************************** -->
           <!-- 아래부터 sql 파일을 통한 DDL, DML 자동 실행 설정법입니다. -->
           <!-- *************************************************** -->
          
           <!-- program 실행할 때마다 DROP 하고 CREATE 하기로 지정함.
               한번 실행하고 나서는 value="none" 으로 바꾸면 테스트에서
               생긴 변동사항을 계속 유지할 수 있다. -->
           <property name="jakarta.persistence.schema-generation.database.action"
                     value="drop-and-create"/>
          
           <!-- 만약에 hibernate 를 사용 중이면, hibernate.hbm2ddl.auto 로 대체가 가능합니다.
			   주의할 점: jakarta.persistence.schema-generation.database.action 와
			   hibernate.hbm2ddl.auto 태그가 둘 중 하나가 ignore 됩니다.
			   저도 다 테스트해보진 않아서 "둘 중 하나"라고 표현합니다.
		   -->
   	       <!--<property name="hibernate.hbm2ddl.auto" value="create" />-->
   
           <!-- "create schema" 문법 사용 가능 여부 지정 -->
           <property name="jakarta.persistence.schema-generation.create-database-schemas"
                     value="true"/>
   
           <!-- 생성과 관련된 ddl 을 script 를 통해서 수행 -->
           <property name="jakarta.persistence.schema-generation.create-source"
                     value="script"/>
   
           <!-- 작성해 놓은 생성 DDL SQL 파일 경로 지정 -->
           <property name="jakarta.persistence.schema-generation.create-script-source"
                     value="META-INF/sql/blog_web/blog_web_ddl.sql"/>
   
           <!-- 삭제와 관련된 ddl 을 script 를 통해서 수행 -->
           <property name="jakarta.persistence.schema-generation.drop-source"
                     value="script"/>
   
           <!-- 작성해 놓은 삭제 DDL SQL 파일 경로 지정 -->
           <property name="jakarta.persistence.schema-generation.drop-script-source"
                     value="META-INF/sql/blog_web/blog_web_drop.sql"/>
   
           <!-- insert 관련 DML SQL 을 작성한 파일 경로 지정 -->
           <property name="jakarta.persistence.sql-load-script-source"
                     value="META-INF/sql/blog_web/blog_web_data.sql"/>
   
           <!-- 의외로 복병인 설정. 위의 sql 들은 사실 각 쿼리를 "한줄로" 작성하는 것이 정석이다. 하지만 그러면 가독성이 너무 안 좋다.
               이를 해결하기 위해서 Hibernate 는 멀티라인이 가능하도록 Extractor 를 제공한다. 사용하면 New Line 이 있어도
               문제없이 실행된다.
            -->
           <property name="hibernate.hbm2ddl.import_files_sql_extractor"
                     value="org.hibernate.tool.schema.internal.script.MultiLineSqlScriptExtractor" />
        </properties>
    </persistence-unit>
</persistence>

참고: SQL 파일들 저장 위치

위에서 작성한 파일 경로들은 아래와 같이 저장된 상태입니다.
META-INF 디렉토리 하단에 SQL 들을 넣을 필요는 없습니다!
resource 디렉토리 안에 자신이 원하는 위치 어디든 상관없습니다!

작성한 SQL 을 보고 싶으신가요?

저의 깃허브 리포지토리 에 방문하시면 볼 수 있습니다.



추천사항

jakarta 가 제공하는 ddl, data-load 기능을 사용한 후,
한번은 <property name="hibernate.hbm2ddl.auto" value="validate"/>
로 생성 테이블과 Entity 클래스가 바인딩이 잘된 건지 확인할 필요가 있습니다.

다만 hibernate.hbm2ddl.auto 를 동작시키기 위해서는 아래와 같이
persistence.xml 파일의 내용을 수정하고 프로그램을 실행시켜야 합니다.

<!-- 기존에 작성되어 있던 jakarta.persistence.schema-generation.database.action 태그 주석처리 -->
<!--<property name="jakarta.persistence.schema-generation.database.action" value="drop-and-create"/>-->

<!-- hibernate.hbm2ddl.auto=validate 기능 활성화 -->
<property name="hibernate.hbm2ddl.auto" value="validate"/>
  • 이러면 작성한 SQL 들은 모두 동작하지 않고, validation check 만하게 됩니다.

이러고 나서 뭔가 잘못되면 콘솔에 대충 아래와 비스무리한 에러 로그가 보이게 됩니다.

Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: wrong column type encountered in column [tag_name] in table [tag]; found [varchar (Types#VARCHAR)], but expecting [bigint (Types#BIGINT)]



주의사항

ddl 관련 sql 파일에서 DO$$ ~ END$$ 문법은 사용을 하지 못하더군요.
계속 에러가 납니다. 됐으면 편했을 거 같지만 어쩔 수 없네요 🤔



참고링크

profile
백엔드를 계속 배우고 있는 개발자입니다 😊

0개의 댓글