기본 콘텐츠로 건너뛰기

spring jpa & egov & maria

spring jpa & egov & maria

AI 생성 이미지: spring jpa & egov & maria
AI 생성 이미지: spring jpa & egov & maria

대부분의 Spring 애플리케이션에서는 `@PersistenceContext`로 `EntityManager`를 주입받고, `@Transactional`으로 트랜잭션을 처리합니다. 하지만 일부 환경(예: 전통적 서블릿 컨테이너에서의 독립 실행이나 Spring MVC가 아닌 구성)에서는 Spring의 프록시 주입과 트랜잭션 어드바이스를 기대할 수 없어, `EntityManagerFactory`를 직접 주입받아 JPA의 생명주기와 트랜잭션을 수동으로 관리해야 할 때가 있습니다.


1. 📄 핵심 JPA 설정 (XML)

다음 XML은 JPA를 구성하기 위한 기본 요소들입니다. `dataSource`와 `LocalContainerEntityManagerFactoryBean`을 정의하며, 예제에서는 `hibernate.hbm2ddl.auto`가 create로 설정되어 있어 애플리케이션 시작 시마다 테이블을 재생성합니다. 운영 환경에서는 이 설정을 사용하면 데이터가 삭제되므로 절대로 권장되지 않습니다.


<!-- 데이터 소스 (DBCP 사용) -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="org.mariadb.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/board?..." />
    <property name="username" value="root"/>
    <property name="password" value="1234"/>
</bean>

<!-- JPA 벤더 어댑터 (Hibernate) -->
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="showSql" value="true"/>
    <property name="generateDdl" value="true"/>
    <property name="databasePlatform" value="org.hibernate.dialect.MariaDB10Dialect"/>
</bean>

<!-- EntityManagerFactory (emf) 설정 -->
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="emf">
    <property name="packagesToScan" value="egovframework" />
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.hbm2ddl.auto">create</prop> <!-- ★ 중요: 실행 시마다 테이블 재생성 -->
        </props>
    </property>
</bean>
            
주의: `hibernate.hbm2ddl.auto`를 `create`로 두면 매번 스키마가 초기화됩니다. 개발 또는 테스트 전용으로만 사용하고, 운영 환경에서는 `validate`나 빈 값으로 두어야 합니다. 또한, 운영 환경에서는 마이그레이션 도구(예: Flyway, Liquibase)를 적용하는 것이 안전합니다.

2. 👨‍💻 EntityManagerFactory를 통한 수동 JPA 관리

Spring이 `EntityManager` 프록시를 제공하지 않는 상황에서는, 컨테이너에 등록된 `EntityManagerFactory` 빈을 주입받아 직접 `EntityManager`를 생성하고 트랜잭션을 관리해야 합니다. 이 방식은 JPA 표준에 충실하지만, 수작업이 많고 예외 처리에 주의가 필요합니다.

2.1. EntityManagerFactory 주입

XML에서 선언한 `id="emf"` 빈을 `@Autowired`로 주입받아 사용합니다. 이 경우 `@PersistenceContext`나 Spring이 관리하는 `EntityManager`는 사용할 수 없다고 가정합니다.


@Autowired
private EntityManagerFactory emf;

// @PersistenceContext 및 EntityManager는 Spring의 관리를 받지 못해 사용 불가능한 상태를 가정합니다.
// @PersistenceContext 사용안됨
// EntityManager em; 사용안됨
        

2.2. 수동 트랜잭션 및 엔티티 처리

`EntityManagerFactory#createEntityManager()`로 획득한 `EntityManager`는 직접 열고 닫아야 합니다. 트랜잭션은 `EntityTransaction`으로 명시적으로 제어합니다. 아래 예시는 기본적인 트랜잭션 패턴으로, 예외 발생 시 롤백하고 항상 `em.close()`로 리소스를 해제합니다.


// 1. EntityManager 획득 (트랜잭션 단위)
EntityManager em = emf.createEntityManager();

// 2. 트랜잭션 시작
EntityTransaction tx = em.getTransaction();
tx.begin();

try {
    // 3. JPA 영속성 작업 수행
    em.persist(boardInfoVO);
    
    // 4. 트랜잭션 커밋
    tx.commit();
} catch (Exception e) {
    if (tx.isActive()) {
        tx.rollback(); // 오류 발생 시 롤백
    }
    throw e;
} finally {
    // 5. EntityManager 닫기 (필수)
    em.close();
}
        

🚀 이 주제, 우리 서비스에 어떻게 적용할까요?

spring jpa & egov & maria를 실제 서비스와 조직에 녹여보고 싶다면, 현재 아키텍처와 운영 방식을 한 번 점검해 보는 것부터 시작해 보세요. 팀 위키나 기술 블로그, 사내 스터디 주제로도 아주 좋습니다.

이 글이 도움이 됐다면, 비슷한 엔터프라이즈 사례 글들도 함께 살펴보면서 우리 조직에 맞는 운영 상용구를 정의해 보세요.

AI 생성 이미지: spring jpa & egov & maria
AI 생성 이미지: spring jpa & egov & maria

3. 🌟 결론 및 권장 사항

수동으로 `EntityManager`와 트랜잭션을 관리하는 방식은 표준 JPA의 전형적인 사용 방법이며, 특정 제약 환경에서는 유일한 선택일 수 있습니다. 다만 Spring 환경에서는 가능한 한 `@Transactional`과 `@PersistenceContext` 기반의 프록시 주입을 사용하여 트랜잭션 경계를 프레임워크에 위임하는 편이 유지보수와 안정성 측면에서 유리합니다.

만약 `@PersistenceContext`가 작동하지 않는다면, 우선 `JpaTransactionManager`가 제대로 설정되었는지와 대상 클래스가 Spring Bean으로 등록되어 AOP 대상이 되는지 확인하세요. 환경을 정비해 `@Transactional`을 적용할 수 있다면 운영상 이점이 큽니다.

© 2025 Spring 개발자 노트.

댓글

이 블로그의 인기 게시물

Java Servlet Request Parameter 완전 정복 — GET/POST 모든 파라미터 확인 & 디버깅 예제 (Request Parameter 전체보기)

Java Servlet Request Parameter 완전 정복 — GET/POST 모든 파라미터 확인 & 디버깅 예제 Java Servlet Request Parameter 완전 정복 웹 애플리케이션에서 클라이언트로부터 전달되는 Request Parameter 를 확인하는 것은 필수입니다. 이 글에서는 Java Servlet 과 JSP 에서 GET/POST 요청 파라미터를 전체 출력하고 디버깅하는 방법을 다양한 예제와 함께 소개합니다. 1. 기본 예제: getParameterNames() 사용 Enumeration<String> params = request.getParameterNames(); System.out.println("----------------------------"); while (params.hasMoreElements()){ String name = params.nextElement(); System.out.println(name + " : " + request.getParameter(name)); } System.out.println("----------------------------"); 위 코드는 요청에 포함된 모든 파라미터 이름과 값을 출력하는 기본 방법입니다. 2. HTML Form과 연동 예제 <form action="CheckParamsServlet" method="post"> 이름: <input type="text" name="username"><br> 이메일: <input type="email" name="email"><b...

PostgreSQL 달력(일별,월별)

SQL 팁: GENERATE_SERIES로 일별, 월별 날짜 목록 만들기 SQL 팁: GENERATE_SERIES 로 일별, 월별 날짜 목록 만들기 데이터베이스에서 통계 리포트를 작성하거나 비어있는 날짜 데이터를 채워야 할 때, 특정 기간의 날짜 목록이 필요할 수 있습니다. PostgreSQL과 같은 데이터베이스에서는 GENERATE_SERIES 함수를 사용하여 이 작업을 매우 간단하게 처리할 수 있습니다. 1. 🗓️ 일별 날짜 목록 생성하기 2020년 1월 1일부터 12월 31일까지의 모든 날짜를 '1 day' 간격으로 생성하는 쿼리입니다. WITH date_series AS ( SELECT DATE(GENERATE_SERIES( TO_DATE('2020-01-01', 'YYYY-MM-DD'), TO_DATE('2020-12-31', 'YYYY-MM-DD'), '1 day' )) AS DATE ) SELECT DATE FROM date_series 이 쿼리는 WITH 절(CTE)을 사용하여 date_series 라는 임시 테이블을 만들고, GENERATE_SERIES 함수로 날짜를 채웁니다. 결과 (일별 출력) 2. 📅 월별 날짜 목록 생성하기 동일한 원리로, 간격을 '1 MONTH' 로 변경하면 월별 목록을 생성할 수 있습니다. TO...

CSS로 레이어 팝업 화면 가운데 정렬하는 방법 (top·left·transform 완전 정리)

레이어 팝업 센터 정렬, 이 코드만 알면 끝 (CSS 예제 포함) 이벤트 배너나 공지사항을 띄울 때 레이어 팝업(center 정렬) 을 깔끔하게 잡는 게 생각보다 어렵습니다. 화면 크기가 변해도 가운데에 고정되고, 모바일에서도 자연스럽게 보이게 하려면 position , top , left , transform 을 정확하게 이해해야 합니다. 이 글에서는 아래 내용을 예제로 정리합니다. 레이어 팝업(center 정렬)의 기본 개념 자주 사용하는 position: absolute / fixed 정렬 방식 질문에서 주신 스타일 top: 3.25%; left: 50%; transform: translateX(-50%) 의 의미 실무에서 바로 쓰는 반응형 레이어 팝업 HTML/CSS 예제 1. 레이어 팝업(center 정렬)이란? 레이어 팝업(레이어 팝업창) 은 새 창을 띄우는 것이 아니라, 현재 페이지 위에 div 레이어를 띄워서 공지사항, 광고, 이벤트 등을 보여주는 방식을 말합니다. 검색엔진(SEO) 입장에서도 같은 페이지 안에 HTML이 존재 하기 때문에 팝업 안의 텍스트도 정상적으로 인덱싱될 수 있습니다. 즉, “레이어 팝업 센터 정렬”, “레이어 팝업 만드는 방법”과 같이 관련 키워드를 적절히 넣어주면 검색 노출에 도움이 됩니다. 2. 질문에서 주신 레이어 팝업 스타일 분석 질문에서 주신 스타일은 다음과 같습니다. <div class="layer-popup" style="width:1210px; z-index:9001; position:absolute; top:3.25%; left:50%; transform:translateX(-50%);"> 레이어 팝업 내용 <...