IBM®
메인 컨텐츠로 가기
    Korea [국가변경]    이용약관
 
 
   
        제품    서비스 & 솔루션    고객지원 & 다운로드    회원 서비스    
메인 컨텐츠로 가기

한국 developerWorks  >  WebSphere | 오픈 소스  >

WebSphere Application Server에서 스프링과 하이버네이트 사용하기

WebSphere Application Server V6에서 V7을 사용해 오픈 소스 환경의 최대 혜택을 얻자

developerWorks
문서 옵션

JavaScript가 필요한 문서 옵션은 디스플레이되지 않습니다.

영어원문

영어원문


제안 및 의견
피드백

난이도 : 고급

Roland Barcia, 공인 IT 전문가, IBM
Tom Alcott, IT 컨설팅 전문가, IBM
Jim Knutson, WebSphere J2EE 아키텍트, IBM
Sara Mitchell, 소프트웨어 엔지니어, IBM
Ian Robinson, STSM, WebSphere 트랜잭션 아키텍트, IBM
Tim Ward, 소프트웨어 엔지니어, IBM

2008 년 11 월 18 일

IBM® WebSphere® Application Server에서 스프링(Spring)이나 하이버네이트(Hibernate)를 사용하고자 하는 이들을 위해 이 글에서는 WebSphere Application server가 가지는 다양한 시나리오용 프레임워크를 구성하는 방법을 설명합니다. 본 글은 프레임워크에 관한 긴 리뷰라기보다는 다양한 시나리오를 성공적으로 구현할 수 있도록 도움을 제공하는 중요한 참고자료입니다(스프링 프레임워크 2.5와 WebSphere Application Server V7을 위해 업데이트됐다).

개요

스프링이라 알려진 스프링 프레임워크는 J2EE™ 환경을 좀 더 접근성 있게 만드는 오픈 소스 프로젝트다. 스프링은 래퍼 클래스와 XML 구성을 통해 J2EE 컨테이너를 사용할 수 있도록 간단한 자바(Java™) 객체용 프레임워크를 제공한다. 스프링의 목표는 프로젝트의 개발 생산성과 런타임 성능을 높이면서 테스트 영역과 애플리케이션 질을 개선하는 것이다.

하이버네이트는 관계형 데이터베이스 테이블, 데이터 질의, 검색 기능에 POJO(Plain Old Java Objects)의 객체 관계형 매핑을 제공하는 오픈 소스 퍼시스턴스/질의 프레임워크다.

많은 조직에서 이 프레임워크들을 사용해 얻는 혜택에 흥미를 보이는 동안 IBM은 고객들이 WebSphere Application Server를 통해 강력하고 안전한 방법으로 이 프레임워크들을 사용할 수 있음을 알게 하고자 한다. 본 글은 이 프레임워크들이 WebSphere Application server에서 어떻게 사용될 수 있는지와 다양한 이용 후기를 통해 최상의 업무 처리를 설명한다. 이를 통해 독자들이 스프링이나 하이버네이트를 가능한 빨리 시작할 수 있도록 한다.




위로


스프링 사용하기

스프링은 개발을 단순하게 할 수 있는 프레임워크로 설명하는게 더 낫지만 경량 컨테이너 환경이라고 일반적으로 설명한다. 인터페이스21(Interface21)이 개발한 스프링 프레임워크는 Ron Johnson이 발표한 의존성 주입(dependency injection) 디자인 패턴을 기반으로 한다. 스프링은 독립적 애플리케이션에서도, 애플리케이션 서버에서도 사용할 수 있다. 주요 개념은 의존성 주입과 AOP(aspect-oriented programming)를 사용해 간단하고 매끄럽게 제품 개발에서 테스팅까지 할 수 있다는 것이다.

스프링과 관련된 가장 빈도 높은 사용 시나리오 중 하나는 간단한 자바 빈(bean) 클래스를 사용해 비즈니스 로직을 구성, 사용하는 것이다. 스프링 문서는 스프링 빈을 사용해 애플리케이션을 만드는 데 필요한 충분한 정보를 제공한다. 여기에는 WebSphere에만 한정된 것은 없다. 이제 WebSphere Application Server를 사용하는 데 필요한 시나리오를 몇 개 소개하겠다. 본 글에서 소개하는 대로 개발한 스프링 애플리케이션은 WebSphere Application Server나 WebSphere Application Server Network Deployment 환경에서 별 문제 없이 작동해야 한다.

특별히 언급하지 않는 한 여기서 제공하는 정보는 모든 플랫폼 상의 WebSphere Application Server 6.0.2.x, 6.1.x, 7.0.x 버전이다.

프레젠테이션 티어 고려사항

본 절에서는 웹 기반 프레젠테이션 티어에서 스프링 사용과 관련된 고려사항을 설명한다.

  • 웹 MVC 프레임워크

    스프링의 웹 MVC 프레임워크는 지금까지 사용했던 다른 프레임워크의 대안이다. 웹 MVC 프레임워크는 JSF(JavaServer Faces)와 Struts를 포함해 WebSphere Application Server가 직접 전달, 사용, 지원했다. 스프링 문서에서는 스프링과 이 웹 프레임워크들을 어떻게 통합하는지 설명한다. IBM은 WebSphere Application Server에 딸린 프레임워크의 제품 지원만을 하지만 MVC 사용은 지원한다.

  • 포틀릿 MVC 프레임워크

    스프링은 포틀릿 MVC 프레임워크(스프링 포틀릿 MVC 프레임워크를 반영한)를 제공하고 WebSphere Portal V6.0, WebSphere Application Server V6.1 포틀릿 컨테이너 모두에서 작동한다(스프링 포틀릿의 예제 모음을 보려면 스프링 포틀릿 MVC를 읽자). WebSphere Application Server V6.1 포틀릿 컨테이너에서 포틀릿을 실행하려면 웹 애플리케이션을 추가로 만들어 포틀릿의 레이아웃과 집합을 정의해야 한다. 포틀릿 집합자(portlet aggregator) 태그 라이브러리를 어떻게 사용하는지에 관한 정보는 WebSphere Application Server Information Center의 포틀릿 컨테이너 소개 글에서 찾을 수 있다. JSF와 포틀릿을 결합해 사용하는 것은 랜더링의 일반적인 방법이다. 스프링, 하이버네이트, JSF, WebSphere Portal이 결합해 함께 사용되는 방법에 관한 정보는 Configuring Hibernate, Spring, Portlets, and OpenInSessionViewFilter with IBM WebSphere Portal에 있다.

데이터 접근 고려사항

본 절에서는 트랜잭션 내의 데이터에 접근하는 스프링 빈 구성에 관련된 고려사항에 관해 설명하겠다.

스프링 프레임워크는 본질적으로 J2EE 환경에서 기본 J2EE 런타임을 대변하는 컨테이너-관리 레이어로 스프링 빈을 감싼다. 다음에 나오는 내용은 스프링 프레임워크가 적절히 WebSphere Application Server 런타임에 위임하고(delegate) 그 런타임과 통합되도록 스프링 빈을 설정하는 방법을 설명한 것이다.

  • WebSphere Application Server에서 구성된 데이터 소스 접근하기

    WebSphere Application Server는 애플리케이션 서버 실행 환경 내에서 사용된 리소스를 관리한다. JDBC 데이터 소스처럼 리소스에 접근하고자 하는 스프링 애플리케이션은 WebSphere로 관리되는 리소스를 활용해야 한다. 이를 위해 다음과 같이 한다.

    1. 개발하는 동안 WAR 모듈은 리소스 레퍼런스로 구성돼야 한다.

      <resource-ref>
      	<res-ref-name>jdbc/springdb</res-ref-name>
      	<res-type>javax.sql.DataSource</res-type>
      	<res-auth>Container</res-auth>
      	<res-sharing-scope>Shareable</res-sharing-scope>
      </resource-ref>
      

    2. EJB JAR 파일에 있어 같은 resource-ref는 데이터 소스에 접근해야 하는 각 EJB에서 선언돼야 한다.

    3. 그러고 나면 데이터 소스 프록시 빈은 WebSphere가 관리하는 리소스 제공자를 참조하는 스프링 애플리케이션 구성 내에서 선언된다.

      <bean id="wasDataSource" 
          class="org.springframework.jndi.JndiObjectFactoryBean">
      	<property name="jndiName" 
      		value="java:comp/env/jdbc/springdb"/>
      	<property name="lookupOnStartup" 
      		value="false"/>
      	<property name="cache" 
      		value="true"/>
      	<property name="proxyInterface" 
      		value="javax.sql.DataSource"/>
      </bean>

      이 프록시 빈으로 데이터 소스를 접근하려면 데이터 소스가 모듈의 구성된 레퍼런트를 사용하는지 확인해야 하므로 WebSphere Application Server가 제대로 관리할 것이다. jndiName 속성 값이 resource-ref에서 선언된 res-ref-name으로 연결된 java:comp/env/ 패턴과 맞춰짐에 주의하자.

      또는 스프링 2.5 전부터 <j2ee:jndi-lookup/> 접근으로 할 수 있었다. jndiName 속성이 resource-ref에서 선언된 res-ref 이름의 실제 값과 resource-ref="true" 속성을 합한 것과 어떻게 맞춰지는지 살펴보자.

      <jee:jndi-lookup id=" wasDataSource "
      	jndi-name="jdbc/springdb"
      	cache="true"
      	resource-ref="true"
      	lookup-on-startup="false"
      	proxy-interface="javax.sql.DataSource"/>

    4. 그러고 나면 스프링 애플리케이션은 데이터 소스 프록시 빈을 제대로 사용할 것이다.

    5. 애플리케이션이 WebSphere Application Server에 배치될 때 리소스 제공자와 리소스 데이터 소스는 스프링 애플리케이션 리소스 레퍼런스가 사용하는 일반적인 방법으로 구성되어야 한다. 배치되는 동안 모듈의 배치 설명자 내에서 선언된 리소스 레퍼런스는 애플리케이션 서버의 구성된 데이터 소스와 결합될 것이다.

  • JDBC 고유의 연결 사용하기

    스프링은 다양한 JDBC 운영이 고유의 JDBC 리소스와 인터랙트해야 할 때 고유 연결에 접근하는 메커니즘을 제공한다. 스프링 JdbcTemplate 클래스는 NativeJdbcExtractor 클래스가 JdbcTemplate 클래스에 설정될 때 이 능력을 활용한다. NativeJdbcExtractor 클래스가 설정되면 스프링은 WebSphere Application Server와 사용될 때 고유의 JDBC 연결까지 항상 드릴다운한다. 이는 다음과 같은 WebSphere의 QoS(quality of service: 서비스 품질) 기능과 혜택을 우회한다.

    • 연결 핸들 추적과 재결합
    • 연결 공유
    • 트랜잭션에 연관
    • 연결 풀 관리

    다른 문제는 WebSphereNativeJdbcExtractor 클래스가 내부 WebSphere 어댑터 클래스에 의존한다는 것이다. 이 내부 클래스들은 WebSphere Application Server의 버전에 따라 다르고 이후에도 변경될 수 있다. 그러므로 이 기능에 의존한 애플리케이션은 없애야 한다.

    NativeJdbcExtractor 클래스 구현 사용(예: WebSphereNativeJdbcExtractor)은 WebSphere Application Server에서 지원되지 않으므로 이를 요구하는 시나리오는 피해야 한다. 대안으로 WebSphere Application Server WSCallHelper 클래스를 사용해 데이터 소스를 위한 업체의 비표준 확장 기능에 접근할 수 있다.

  • 스프링으로 트랜잭션 사용하기

    WebSphere Application Server는 트랜잭션 프로세스와 리소스 제공자 연결 관리에 확실하고 확장성 있는 환경을 제공한다. JDBC, JMS, 자바 커넥터(Java Connector) 리소스 어댑터를 연결하는 것은 글로벌 트랜잭션 사용 여부에 관계없이 WebSphere Application Server에서 관리한다. 글로벌 트랜잭션이 없어도 모든 리소스 제공자 연결이 접근되는 곳에는 런타임 컨텍스트가 항상 존재한다. WebSphere Application Server는 이 런타임 컨텍스트를 LTC(local transaction containment) 수준으로 참조한다. 글로벌 트랜잭션이 없는 곳에는 항상 LTC가 있고 리소스 접근은 항상 글로벌 트랜잭션이나 LTC가 있는 곳에서 런타임으로 관리된다. 트랜잭션 컨텍스트 관리의 무결성을 확실히 하려면(그리고 이로써 트랜잭션 리소스를 제대로 관리하려면) WebSphere Application Server는 애플리케이션이나 WebSphere Application Server에 배치된 애플리케이션 프레임워크에 javax.transaction.TransactionManager 인터페이스를 노출시키지 말아야 한다.

    스프링의 트랜잭션 제어 하에서 프로그램적 폼이나 선언적 폼 모두를 포함해 드라이브 리소스를 업데이트하는 데는 몇 가지 방법이 있다. 선언적 폼은 자바 주석(annotation)과 XML 지시자 폼 모두를 갖는다. 스프링 2.5와 WebSphere Application Server V6.0.2.19, V6.1.0.9, 그 이후 버전을 사용한다면 스프링의 선언적 트랜잭션 모델의 모든 지원을 받을 수 있다. 스프링 2.5는 WebSphereUowTransactionManager라는 WebSphere Application Server용 새 PlatformTransactionManager 클래스를 가지는데 이는 트랜잭션 컨텍스트 관리용 WebSphere Application Server 지원의 UOWManager 인터페이스를 사용한다. WebSphere Application Server의 UOWManager 클래스를 통해 트랜잭션 분리를 관리하려면 리소스 제공자에 접근할 때마다 적절한 글로벌 트랜잭션이나 LTC 컨텍스트가 있는지 확인해야 한다. 하지만 스프링의 이전 버전에서는 웹과 EJB 컨테이너로 리소스를 관리하는 능력으로 내부 WebSphere 인터페이스를 사용하고 애플리케이션 사용을 지원하지 않았다. 이는 컨테이너를 모르는 상태로 남겨둠으로써 데이터 오염을 초래했다.

    스프링 2.5나 그 이상 버전에서 선언적 트랜잭션 분리는 다음의 WebSphere 트랜잭션 지원용 선언을 사용해 WebSphere Application Server에서 지원된다.

    <bean id="transactionManager"
    	class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/>

    그러고 나면 이 선언을 참조하는 스프링 빈은 표준 스프링 의존성 주입을 사용해 트랜잭션 지원을 사용한다. 예를 들어 다음과 같다.

    <bean id="someBean" class="some.class">
    	<property name="transactionManager" >
    		<ref bean="transactionManager"/>
    	</property>
    ...
    </bean>
    <property name="transactionAttributes">
    	<props>
    		<prop key="*">PROPAGATION_REQUIRED</prop>
    	</props>
    	</property>

    또는 스프링 2.5 이전 버전에서 스프링의 AspectJ 지원이 활용될 수 있다. 다음 예에서 <tx:advice/>는 애플리케이션의 다양한 부분에 적용될 수 있다. 이는 "get"으로 시작되는 모든 메서드는 PROPAGATION_REQUIRED고 "set"으로 시작되는 모든 메서드는 PROPAGATION_REQUIRES_NEW라는 것을 의미한다. 여타 메서드는 전부 기본 트랜잭션 설정을 사용한다.

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
       <tx:attributes>
          <tx:method name="get*" propagation="REQUIRED" read-only="true" />
          <tx:method name="set*" propagation="REQUIRES_NEW" />
          <tx:method name="*" />
       </tx:attributes>
    </tx:advice>

    <aop:config/> 태그는 이 설정들을 MyService 클래스 내에서 정의된 여타 실행된 연산에 적용한다.

    <aop:config>
       <aop:pointcut id="myServiceOperation" 
          expression="execution(* sample.service.MyService.*(..))"/>
       <aop:advisor advice-ref="txAdvice" 
          pointcut-ref="myServiceOperation"/>
    </aop:config>

    트랜잭션 설정을 선언하는 또 다른 대안 메커니즘은 스프링 주석 기반의 트랜잭션 지원을 사용하는 것이다. 이를 위해서는 자바 5 이상을 사용해야 하므로 WebSphere Application Server V6.0.2.x에서는 사용할 수 없다.

    다음을 Spring.xml 구성에 추가하자.

    <tx:annotation-driven/>

    그러고 나면 트랜잭션 속성을 요구하는 메서드는 @Transactional 주석으로 표시된다.

    @Transactional(readOnly = true)
    public String getUserName()
    { ...

    @Transactional 주석은 퍼블릭 메서드에 주석을 달 때만 사용됨에 주의하자.

    WebSphereUowTransactionManager는 각각의 스프링 트랜잭션 속성을 지원한다.

    • PROPAGATION_REQUIRED
    • PROPAGATION_SUPPORTS
    • PROPAGATION_MANDATORY
    • PROPAGATION_REQUIRES_NEW
    • PROPAGATION_NOT_SUPPORTED
    • PROPAGATION_NEVER

    org.springframework.transaction.jta.WebSphereUowTransactionManager를 제공하지 않는 스프링의 이전 버전과 com.ibm.wsspi.uow.UOWManager를 제공하지 않는 WebSphere Application Server의 V6.0.2.19나 V6.1.0.9 이전 버전에서 WebSphere Application Server의 트랜잭션은 이 스프링 구성을 통해 가능하다.

    <bean id="transactionManager" 
    	class="org.springframework.transaction.jta.JtaTransactionManager">
    		<property name="autodetectTransactionManager"value="false" />
    </bean>

    이 구성 지원은 PROPAGATION_NOT_SUPPORTED와 PROPAGATION_REQUIRES_NEW를 포함하지 않는 트랜잭션 속성의 제한된 집합이다. PROPAGATION_NOT_SUPPORTED와 PROPAGATION_REQUIRES_NEW 능력도 제공하는 스프링 클래스 org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean은 지원되지 않는 내부 WebSphere Application Server 인터페이스를 사용하고 WebSphere Application Server 내에서는 사용될 수 없다.

  • 스프링 JMS 사용하기

    JDBC 데이터 리소스에 접근하는 것처럼 스프링 애플리케이션은 JMS 목적에 접근할 의도를 가지고 있으며 WebSphere가 관리하는 JMS 리소스 제공자를 사용해야 한다. 스프링 JndiObjectFactoryBean을 ConnectionFactory용 프록시로 사용하는 것 같은 패턴으로 JMS 리소스가 제대로 관리됐는지 확인할 것이다.

    JMS 메시지 보내기나 동기화 JMS 메시지 수신의 경우 JMSTemplates가 사용될 수 있다. 여기에는 JNDI와 진짜 동적 해결 모두를 통한 스프링의 동적 목적 해결 기능 사용이 포함된다.

    다음 예는 ConnectionFactory용 리소스 레퍼런스 구성을 보여준다. 이 레퍼런스는 애플리케이션 배치 중에 애플리케이션 서버의 JNDI 이름공간에 저장된, 구성되고 관리된 ConnectionFactory와 매핑된다. ConnectionFactory는 메시징을 수행해야 하고 스프링 JMSTemplate에 주입돼야 한다.

    <resource-ref>
          <res-ref-name>jms/myCF</res-ref-name>
          <res-type>javax.jms.ConnectionFactory</res-type>
          <res-auth>Container</res-auth>
          <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>

    이제 애플리케이션 내에 JMSTemplate를 찾고 주입할 수 있는 ConnectionFactory용 JNDI 이름이 정의된다.

    <jee:jndi-lookup id="jmsConnectionFactory" jndi-name=" jms/myCF "/>
    
    <bean id="jmsQueueTemplate" 
             class="org.springframework.jms.core.JmsTemplate">
      <property name="connectionFactory">
          <ref bean="jmsConnectionFactory"/>
       </property>
       <property name="destinationResolver">
          <ref bean="jmsDestResolver"/>
       </property>
        ...
    </bean>
    
    <!-- A dynamic resolver -->
    <bean id="jmsDestResolver" class=" 
          org.springframework.jms.support.destination.DynamicDestinationResolver"/>
    
    <!-- A JNDI resolver -->
    <bean id="jmsDestResolver" 
    	class=" org.springframework.jms.support.destination.JndiDestinationResolver"/>

    런타임에 JMSTemplate은 WebSphere Application Server에 구성된 목적의 관리적 이름을 기반으로 JNDI 이름(애플리케이션 리소스 레퍼런스에서 구성된 대로)이나 "동적" 해결을 통해 목적을 위치할 수 있다. 예를 들어 JMS myQueue 대기행렬의 경우 jms/myQueue의 JNDI 레퍼런스로 묶인다.

    JNDI 해결:
    jmsTemplate.send("java:comp/env/jms/myQueue", messageCreator);

    동적 해결:
    jmsTemplate.send("myQueue", messageCreator);

    J2EE MDB(message-driven beans)의 대안으로 스프링은 비동기적으로 JMS 메시지 내에서 묶는 프로세스용 메시지 구동의 POJO 모델을 제공한다. DefaultMessageListenerContainer 클래스만이 JMS 대기행렬에서 설정된 POJO로 가는 메시지를 관리한다. 그 POJO는 javax.jms.MessageListener 구현이어야 한다.

    WebSphere Application Server 환경에서 WorkManagerTaskExecutor 클래스도 지정해야 할 것이다. 이는 DefaultMessageListenerContainer 클래스가 서버로 관리되는 스레드 풀을 위임할 것이라는 뜻이다. DefaultMessageListenerContainer 또한 에서 언급했듯이 WebSphereUowTransactionManager를 통해 서버의 트랜잭션 관리로 구성될 것이다.

    <bean id="messageListener" class="sample.ExampleMessageListener" />
    
       <bean id="msgListenerContainer"
          class="org.springframework.jms.listener.DefaultMessageListenerContainer">
          <property name="connectionFactory" ref="jmsConnectionFactory" />
          <property name="destination" ref="jmsQueue" />
          <property name="messageListener" ref="messageListener" />
          <property name="transactionManager" ref="transactionManager" />
          <property name="taskExecutor" ref="myTaskExecutor" />
       </bean>
    
       <bean id="myTaskExecutor"
          class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
          <property name="workManagerName" value="wm/default" />
       </bean>
    
       <bean id="transactionManager"
          class="org.springframework.transaction.jta.WebSphereUowTransactionManager" />
    
       <jee:jndi-lookup id="jmsConnectionFactory" jndi-name="jms/CF1" />
    
       <jee:jndi-lookup id="jmsQueue" jndi-name="jms/jmsQueue" />

    메시지 구동의 POJO 모델이 사용될 수 있는 동안 J2EE MDB가 워크로드 관리와/또는 고가용성이 필요한 WebSphere Application Server 구성에서 직접 사용되는 것이 좋다. 그 어떤 스프링 JMS MessageListenerContainer 유형도 지원되지 않는다는 것에 주의하자. 이 유형은 관리되지 않는 스레드를 시작할 수 있고 자바 EE 환경에서 애플리케이션으로 호출되면 안 되는 JMS API를 사용하기 때문이다.

  • 스프링으로 JPA 사용하기

    EJB 3.0 명세는 휴대용 퍼시스턴트 자바 엔티티를 제공하는 것으로 JPA(Java Persistence API)를 정의한다. WebSphere Application Server V7과 WebSphere Application Server V6.1 EJB 3 기능 팩 모두 EJB 3와 JPA 구현을 제공한다. 또한 WebSphere Application Server V6.1과 JPA의 아파치 OpenJPA 구현을 사용할 수 있다(참고자료를 보자). 스프링이 JAP 구현과 결합될 때 스프링의 JPA 헬퍼 클래스(org.springframework.orm.jpa 패키지에 있는)를 사용하기보다는 JPA를 직접 사용해야 한다.

    WebSphere Application Server V6.1과 그 이후 버전은 JTA나 리소스-로컬 중 하나의 트랜잭션 유형을 갖는 JPA 애플리케이션으로 관리되는 엔티티 관리자를 지원한다. JTA 엔티티 관리자는 애플리케이션 서버의 기본 JTA 트랜잭션 지원을 사용하는데 에서 설명했듯 트랜잭션 분리는 표준 J2EE 기술이나 스프링의 선언적 트랜잭션 모델 중 하나를 사용해 정의될 수 있다.

    JPA를 사용하는 DAO(data access object)는 애플리케이션이 사용하는 JPA EntityManager용 퍼시스턴스 컨텍스트를 정의하는 persistence.xml로 패키지된다. 예를 들어 데이터 소스와 JNDI 이름 "java:comp/env/jdbc/springdb"를 사용하는 JTA 엔티티 관리자용 persistence.xml은 다음과 같이 설정될 수 있다.

    <persistence 
       xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
       http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
    	<persistence-unit name="default" transaction-type="JTA">
    	<provider> org.apache.openjpa.persistence.PersistenceProviderImpl </provider>
    	<jta-data-source> java:comp/env/jdbc/springdb </jta-data-source>
    	<properties>
    		<property name="openjpa.TransactionMode" value="managed" />
    		<property name="openjpa.ConnectionFactoryMode"value="managed" />
    		<property name="openjpa.jdbc.DBDictionary" value="db2" />
    	</properties>
    	</persistence-unit>
    </persistence>

    openjpa.TransactionMode와 openjpa.ConnectionFactoryMode 속성을 "관리되게끔" 설정하려면 JPA 엔티티 관리자는 트랜잭션과 연결의 관리를 WebSphere Application Server에 위임해야 한다. DAO는 스프링의 선언적 트랜잭션 분리를 에서 설명했듯이 사용할 것이다.

    JPA EntityManager의 주석 스타일 주입도 가능하다. 이는 표준 JPA와 일치한다.

    @PersistenceContext
    private EntityManager em;

    스프링 XML 구성에 EntityManager를 주입하려면 이 XML 코드가 필요하다.

    <!-- bean post-processor for JPA annotations -->
    <bean class=
    	"org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

    스프링은 이 XML 파일에서 정의된 어떤 EntityManagerFactory에서든 EntityManager를 만들 것이다. 하나 이상이 존재한다면 실패할 것이다. 이 중 하나(만)을 사용해 EntityManagerFactory를 만들자.

    • 스프링의 기본 구성 사용하기
      <bean id="entityManagerFactory"
            class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
         <property name="persistenceUnitName" value="default"/>
      </bean>

    • 스프링의 고급 구성 사용하기
      <bean id="myEmf" 
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="ds"/>
      </bean>
      
      <jee:jndi-lookup 
          id="ds" 
          jndi-name="jdbc/ds" 
          cache="true" 
          expected-type="javax.sql.DataSource"
      />

    물론 WebSphere Application Server V7과 WebSphere Application Server V6.1 EJB 3 기능 팩의 순수 EJB 3 지원을 사용해도 주석과 JPA로부터 혜택을 얻을 수 있다. 어떤 것을 사용하든 아래와 같이 JPA API를 사용해 EntityManagerFactory를 만들 수 있다. 이 접근은 EJB 3 환경이 아닌 곳에서는 사용하지 않는 게 좋다. 만들어진 어떤 EntityManagers도 제대로 관리되지 않기 때문이다. 하지만 EJB 3 환경 하에서는 이 접근을 사용해 스프링과 JPA 구성을 구분할 수 있다.

    <bean id="myEmf" 
       class="javax.persistence.Persistence" 
       factory-method="createEntityManagerFactory" >
      <constructor-arg type="java.lang.String" value="default"/>  
    </bean>

  • IBM JDK 6

    IBM JDK 6 상에서 작동하는 WebSphere Application Server V7은 이 JIRA 내에서 명시한 스프링 문제 때문에 스프링 프레임워크 V2.5.5 이전 버전에서는 사용할 수 없다.

통합 및 관리 고려사항

  • JMX와 Mbean

    스프링 JMX Mbean은 WebSphere Application Server의 컨테이너 관리자 MbeanServer에 등록돼 있을 때만 WebSphere Application Server V6.1과 그 이후 버전에서 지원한다. 서버 속성이 지정되지 않으면 MbeanExporter는 자동으로 작동하는 MbeanServer의 결함을 잡아내려고 한다. 그러므로 WebSphere Application Server에서 애플리케이션을 실행할 때 스프링 프레임워크는 컨테이너의 MbeanServer를 위치시킬 것이다.

    MbeanServerFactory를 사용해 MbeanServer를 인스턴스화했어도, 이를 MbeanExporter에 주입시키면 안 된다. 또한 WebSphere Application Server는 인바운드 JMX 포트를 열어 스프링의 ConnectorServerFactoryMBean이나 JMXConnectorServer를 사용해 로컬 MbeanServer를 클라이언트에 노출하는 것도 지원하지 않는다.

    WebSphere Application Server 6.1 버전 이전에서는 스프링 JMX Mbean을 지원하지 않는다.

  • WebSphere Application Server에서 스프링 Mbean 등록하기

    WebSphere Application Server Mbean은 다음과 같이 등록될 때 javax.management.ObjectName에 의해 식별된다.

    WebSphere:cell=99T73GDNode01Cell,name=JmxTestBean,node=99T73GDNode01,
    process=server1,type=JmxTestBeanImpl

    이는 등록에서 제외될 때 같은 "완전한 자격을 취득한" 이름을 봐야지, Mbean의 간단한 이름 속성을 봐서는 안 된다는 뜻이다. 최고의 접근은 ObjectName 인스턴스의 생성을 캡슐화한 인터페이스이자 빈을 등록할 때 MbeanExporter를 사용해 ObjectNames를 취득할 수 있는 org.springframework.jmx.export.naming.ObjectNamingStrategy를 구현하는 것이다. 예는 스프링 프레임워크 포럼에서 찾을 수 있다. 등록한 빈에 ObjectNamingStrategy 인스턴스를 추가할 수 있다. 이렇게 하면 애플리케이션을 제거했을 때 Mbean이 제대로 등록에서 제거할 수 있을 것이다.

    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"
       lazy-init="false">
    <property name="beans">
    	<map> <entry key="JmxTestBean" value-ref="testBean" /> </map>
    </property>
    <property name="namingStrategy" ref="websphereNamingStrategy" />
    ...
    </bean>

  • Mbean ObjectNames와 통보

    WebSphere Application Server에서 Mbean용으로 완벽한 자격을 지닌 ObjectName 사용으로 통보를 사용하도록 완전히 정의하는 것이 좋다. 이 JIRA는 대신 스프링 빈 이름을 사용하고 수리가 가능하게끔 하지만 이는 스프링의 적절한 버전에서만 가능하다.

    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" 
       lazy-init="false">
    	<property name="beans">
    		<map>
    		  <entry key="JmxTestBean" value-ref="testBean" />
    		</map>
    	</property>
    	<property name="namingStrategy" ref="websphereNamingStrategy" />
    	<property name="notificationListenerMappings">
    		<map>
    		  <entry key="WebSphere:cell=99T73GDNode01Cell, name=JmxTestBean,
    			node=99T73GDNode01, process=server1, type=JmxTestBeanImpl">
    			  <bean class="client.MBeanListener" />
    		  </entry>
    		</map>
    	</property>
    </bean>

  • System z 다중 호출/단일 호출 한계

    Mbean 서술자에서 스프링이 플랫폼 특유 필드의 명세를 허락하지 않으므로 스프링 JMX는 WebSphere Application Server V6.1 상의 다중-SR 서버에서 작동하겠지만 배치 옵션에 제한을 받을 것이다. WebSphere Application Server는 unicall 전략을 기본으로 하기 때문에 Mbean(확실치 않은 SR)의 단 하나의 인스턴스만이 요청을 실행하도록 요구할 것이다. 이는 몇 가지 시나리오에는 충분하겠지만 애플리케이션이 다중 호출(multicall)과 단일 호출(unicall) 메서드의 결합을 선언할 수 있는 것이 좋고 집합 로직에서 가능한 결과를 가질 수 있을 것이다.

  • 스케쥴링과 스레드 풀링

    스프링은 스케쥴링 작업에 사용될 수 있는 몇 가지 TaskExecutor 클래스를 제공한다. 비동기적으로 실행되는 WebSphere Application Server로 지원되는 스프링 TaskExecutor만이 WebSphere Application Server로 관리되는 스레드 풀을 적절히 활용하고 구성된 WorkManager로 위임하는 스프링 WorkManagerTaskExecutor 클래스다. 다른 TaskExecutor 구현이 관리되지 않은 스레드를 시작해야 한다.

    WebSphere Application Server 내의 관리자 콘솔에서 Resources => Asynchronous beans => Work managers를 선택해 WorkManager를 설정할 수 있다. 그러고 나면 리소스용 JNDI 이름이 스프링 config 파일에서 workManagerName 속성으로 사용돼 WorkManagerTaskExecutor를 정의한다. 이 예는 WebSphere Application Server의 DefaultWorkManager JNDI 이름이나 wm/default를 사용한다.

    <bean id="myTaskExecutor" 
    	class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
      <property name="workManagerName" value="wm/default" />
    </bean>
    

  • 클래스로더

    스프링과 WebSphere Application Server 모두 몇 가지 오픈 소스 프로젝트를 사용하는데 불행하게도 가지고 있는 프로젝트의 버전은 일반적으로 항상 일치하지 않는다. 스프링 의존성은 애플리케이션의 부분으로 패키지돼야 하고 서버는 아래서 설명한 것처럼 설정해 충돌을 피해야 한다. 그렇지 않으면 클래스로더는 런타임이나 애플리케이션에 맞지 않는 버전을 로드할 것이다. 대체로 이는 클래스, ClassCastExceptions 또는 java.lang.VerifyErrors와 매치되지 않는 버전에 따라 로그에서 예외가 나타난다.

    JCL(Jakarta Commons Logging)을 예로 들 수 있다. 애플리케이션 서버로 제공되기보다(예를 들어 애플리케이션 코드에 끼워진) 애플리케이션 사용을 위해 JCL을 구성하거나 JCL의 다른 버전을 활용하려면 WebSphere Application Server 상의 특별한 구성을 요구한다. 배치된 애플리케이션을 구성해 일반적으로 사용된 기술의 끼워진 버전을 사용하는 방법에 관한 전략을 위해 Integrating Jakarta Commons Logging을 보자. 지원 웹 사이트에서 WebSphere Application Server V6.x 제품에 끼워진 JCL을 어떻게 구성하는지에 관한 업데이트를 주의깊게 살펴보자. 이는 충돌의 그저 한 예에 불과하다. JDOM의 애플리케이션 사용이나 JavaMail의 특정 버전을 포함할 수도 있다. WebSphere Application Server의 JAR 파일과 다른 패키지를 바꾸는 것은 다른 버전이나 이후 버전에서는 지원되지 않는다.

    WebSphere Application Server에서 스프링 사용자에게 재앙이 되는 또 다른 클래스로더 문제는 스프링이 리소스를 로드하는 방법이다. 리소스는 메시지 번들 같은 것을 포함할 수 있고 클래스로더 계층 및 계층 내의 리소스를 위치하는 다양한 정책과 함께 의도하지 않은 위치에서 발견되는 일반적인 이름을 사용할 수 있다. WebSphere Application Server 클래스로더 뷰어는 이 문제를 해결하는 데 사용할 수 있다. 이것과 일반 라이브러리의 다른 버전을 결합하려면 애플리케이션이 리소스가 유일한 이름으로 바꿔야 할 것이다.

    James Estes가 스프링 포럼에서 설명한 예에는 EJB 프로젝트와 EAR 파일에 패키지된 웹 프로젝트가 있다. 설명된 솔루션은 spring.jar 파일을 WEB-INF/lib과 EAR의 최상위 레벨 모두에 추가하여 WEB 프로젝트용 클래스 정책을 PARENT LAST에 설정해 WEB-INF/lib의 버전을 먼저 찾는 것이다. EJB 프로젝트는 EAR의 버전을 사용한다.

디자인 고려사항

스프링 프레임워크가 제공하는 몇몇 인프라 서비스는 표준 기반의 애플리케이션 서버 런타임을 제공하는 서비스를 복제한다. 거기다 기본 J2EE 애플리케이션 서버에서 스프링 프레임워크 인프라의 추상화는 보안이나 워크로드 관리, 고가용성 같은 서비스의 애플리케이션 서버 런타임 QoS 통합을 방해하게 되어 있다. 그 결과 WebSphere Application Server에 애플리케이션을 배치하는 데 스프링 프레임워크를 사용하려면 WebSphere Application Server가 제공하는 서비스 품질을 해치지 않는 범위 내에서 조심스럽게 애플리케이션을 디자인해야 한다. 권고사항이 없을 경우 공개 표준을 기반으로 애플리케이션을 개발하고 유연하게 배치하기 위해 WebSphere Application Server가 제공하는 서비스를 직접 사용하는 것이 좋다.

  • 관리되지 않은 스레드

    관리되지 않는 스레드를 만드는 스프링 시나리오도 있다. WebSphere Application Server는 관리되지 않은 스레드를 알지 못하고 자바 EE의 컨텍스트적 정보에 접근하지 않는다. 거기다 WebSphere Application Server가 모르는 사이 리소스를 사용할 수 있고 관리자가 통제하지 못하거나 리소스 사용을 남길 수 있으며 애플리케이션 서버의 해 없는 정지 기능이나 고장에서 리소스를 복구하는 능력을 마비시킬 수 있다. 애플리케이션은 다음과 같이 관리되지 않은 스레드를 시작하는 원인을 피해야 한다.

    • registerShutdownHook

      AbstractApplicationContext나 이것의 하위클래스 사용을 피하자. 자바 VM에 스레드를 만들고 등록해 셧다운에 실행해 ApplicationContext를 닫는 퍼블릭 메서드인 registerShutdownHook이 있다. 애플리케이션은 WebSphere 컨테이너에서 일반적인 생명주기 공지를 받아 ApplicationContext를 닫도록 호출함으로써 이를 피할 수 있다.

    • WeakReferenceMonitor

      스프링의 편리한 클래스로 간단히 EJB 컴포넌트를 개발할 수 있지만 이 편리한 클래스들이 WeakReferenceMonitor를 사용해 정제 목적으로 관리되지 않은 스레드를 생성할 수 있음에 유의하자.

  • 스케쥴링

    스프링은 몇 가지 스케쥴링 패키지를 제공(하거나 통합)하지만 WebSphere Application Server로 관리되는 스레드와 작업하는 스프링 스케쥴링 패키지는 CommonJ WorkManager밖에 없다. Quartz나 JDK Timer 같은 다른 패키지는 관리되지 않은 스레드를 시작시키므로 피해야 한다.




위로


하이버네이트 사용하기

하이버네이트는 POJO용 오픈 소스 퍼시스턴스 프레임워크로 XML 구성 파일을 사용해 POJO의 객체 관계형 매핑을 관계형 데이터베이스 테이블에 제공한다. 하이버네이트 프레임워크는 데이터 퍼시스턴스용 애플리케이션이 호출하는 데이터 접근 추상화 레이어다. 또한 데이터 질의와 검색 기능을 매핑하는 것처럼 자바 클래스와 데이터베이스 테이블(그리고 자바 데이터 유형에서 SQL 데이터 유형으로)을 매핑한다. 하이버네이트는 필요한 SQL 호출을 생성하고 결과 집합 핸들링과 객체 변환을 관리한다.

OpenJPA처럼 하이버네이트도 자바 EE 5의 필수 부분인 JPA(Java Persistence APIs) 명세를 구현한다(하이버네이트 사용에 대해서는 참고자료의 developerWorks 기사를 보자).

이용 시나리오

다음 시나리오는 WebSphere Application Server와 WebSphere 스택 제품으로 하이버네이트를 사용하는 방법에 대한 가능한 시나리오를 설명하고 있다. 이것들은 예제 시나리오일 뿐이며 권유된 시나리오로 받아들여서는 안 된다.

  • WebSphere Application Server 데이터 소스 사용하기

    하이버네이트로 WebSphere Application Server의 데이터베이스에 연결하려면 자바 EE(구 J2EE) 명세에서 위임한 리소스 레퍼런스를 사용해야 한다. 이는 WebSphere Application Server가 연결 풀링, 트랜잭션 시맨틱, 격리 수준에 맞는 행위를 제공할 수 있음을 확인해 준다. 하이버네이트는 hibernate.connection.datasource 속성(하이버네이트 구성 파일에서 정의된)을 설정해 모듈의 배치 설치자에서 정의된 리소스 레퍼런스(예를 들어 java:comp/env/jdbc/myDSRef)를 참조함으로써 WebSphere Application Server에서 데이터 소스를 찾아오도록 구성된다.

    <property name="hibernate.connection.datasource">
    	java:/comp/env/jdbc/myDSRef
    </property>

    웹 애플리케이션용 자바 EE 리소스 레퍼런스는 WAR 파일 수준에서 정의된다. 이는 컨테이너 내의 모든 서블릿과 자바 클래스가 리소스 레퍼런스를 공유한다는 뜻이다. EJB 모듈 내의 리소스 레퍼런스는 개별 EJB 컴포넌트에서 정의된다. 이는 많은 EJB 컴포넌트가 같은 하이버네이트 구성을 사용한다면 각 EJB는 각 EJB 컴포넌트 상의 같은 레퍼런스 이름을 정의해야 한다는 뜻이다. 나중에 논의하겠지만 이러한 점 때문에 복잡해질 수 있다.

    데이터 소스가 구성되면 하이버네이트가 제대로 작동하고 있음을 확인하는 다음 중 한 단계로 트랜잭션 지원을 적절히 구성한다.

  • 트랜잭션 전략 구성

    하이버네이트는 트랜잭션에 제대로 작동하기 위해 두 가지 필수 구성을 필요로 한다. 첫 번째는 트랜잭션 제어를 정의하는 hibernate.transaction.factory_class고 두 번째는 트랜잭션 동기화 등록용 메커니즘을 정의하는 hibernate.transaction.manager_lookup_class다. 그러므로 데이터베이스로 동기화된 변화를 해야 할 때 트랜잭션 말미에 퍼시스턴스 매니저가 보고를 받는다. 트랜잭션 제어시 컨테이너-관리의 구성과 빈-관리의 구성 모두 지원된다. 다음 속성들은 WebSphere Application Server에서 하이버네이트를 사용할 때 Hibernate.cfg.xml에 설정해야 한다.

    • 컨테이너-관리 트랜잭션용

      <property name="hibernate.transaction.factory_class">
      	org.hibernate.transaction.CMTTransactionFactory
      </property>
      <property name="hibernate.transaction.manager_lookup_class">
      	org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
      </property>

    • 빈-관리 트랜잭션용

      <property name="hibernate.transaction.factory_class">
      	org.hibernate.transaction.JTATransactionFactory
      </property>
      <property name="hibernate.transaction.manager_lookup_class">
      	org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
      </property>
      <property name="jta.UserTransaction">
      	java:comp/UserTransaction
      </property >

    jta.UserTransaction 속성은 WebSphere 컨테이너에서 UserTransaction 객체 인터페이스의 인스턴스를 얻기 위해 factory 클래스를 구성한다.

    hibernate.transaction.manager_lookup_class 속성은 WebSphere Application Server V6.x과 그 이상 버전, WebSphere Business Integration Server Foundation V5.1과 그 이상 버전의 WebSphere 플랫폼에서 지원된다. 이 속성은 하이버네이트를 구성하여 WebSphere Business Integration Server Foundation V5.1과 WebSphere Application Server V6.0에서 소개된 ExtendedJTATransaction 인터페이스를 사용한다. WebSphere ExtendedJTATransaction 인터페이스는 JTA 1.1 명세를 통해 자바 EE 5에서 정형화된 패턴을 구축한다.

  • 지원되지 않는 트랜잭션 구성

    하이버네이트 문서는 WebSphere Application Server 버전 4와 5 제품에서 작동하는 트랜잭션 전략 구성을 설명한다. 하지만 이 구성들은 내부 WebSphere 인터페이스를 사용하고 이전 버전에서는 지원되지 않는다. 하이버네이트의 트랜잭션 구성 중 에서 설명한 것만 지원된다. 이는 이전에 언급했듯이 하이버네이트 사용이 WebSphere Business Integration Server Foundation V5.1과 WebSphere Application Server Version 6.x 및 그 이후 버전에서만 지원된다는 뜻이다.

  • WebSphere Application Server 환경 내에서 하이버네이트의 사용 패턴

    WebSphere Application Server에서 하이버네이트를 사용할 때 하이버네이트의 세션 당 요청과 긴 대화 패턴이 모두 가능하다. 세션 당 요청이 더 나은 확장성을 제공하지만 고객은 자신의 애플리케이션에 맞는 것이 어떤 것인지 선택해야 한다.

    • 다중 격리 수준

      공유 가능한 연결은 다중 리소스 사용자가 기존 연결을 공유하도록 함으로써 WebSphere Application Server에서 성능을 높인다. 하지만 공유 가능한 연결과 다중 격리 수준 모두가 필요하다면 각 연결 구성에 따라 resource-ref와 하이버네이트 session-factory를 나눠 정의해야 한다. 공유된 연결의 격리 수준을 변경하는 것은 불가능하다. 그러므로 hibernate.connection.isolation 속성을 사용해 공유 가능한 연결 상의 격리 수준을 설정하는 것 역시 불가능하다. 연결 공유에 관한 정책과 제한에 관한 더 많은 정보는 Sharing connections in WebSphere Application Server V5를 읽기 바란다(이 글은 일반적으로 WebSphere Application Server V5 상의 모든 공유된 연결 사용을 다루지만 연결 공유에 관한 조언은 V6.x에서 작동하는 하이버네이트에도 통용된다).

    • 웹 애플리케이션

      하이버네이트의 긴 대화 세션은 HttpSession 객체에서 사용되고 저장될 수 있다. 하지만 하이버네이트 세션은 활동적인 인스턴스를 가지므로 HttpSession에 저장하는 것은 확장 가능한 패턴이 될 수 없다. 세션은 연결되거나 추가 클러스터 멤버를 복제해야 하기 때문이다. HttpSession은 오히려 직렬화되지 않은 객체(10KB에서 50KB 정도로 작을 경우)를 저장하는데, 그리고 업데이트가 필요할 때 새 하이버네이트 세션과 재결합하는 데 사용하는 게 좋다. HttpSession은 캐싱이 아니라 북마킹에 사용할 때 가장 좋기 때문이다. HttpSession에서 메모리를 최소화하는 방법은 Improving HttpSession Performance with Smart Serialization을 읽어보자. 다음 절에서 설명하겠지만, HttpSession을 캐시로 사용하는 대신 ObjectGrid나 DistributedObjectCache같은 WebSphere 데이터 캐싱 기술을 사용해보자.

    고성능이고 확장성 있는 애플리케이션에 관한 모범 사례는 Performance Analysis for Java Websites 책을 읽어보기 바란다.

출판할 당시 WebSphere Application Server와 결합하는 하이버네이트의 클러스터 행동의 캐시가 결정되지 않았다. 그러므로 이를 사용하는 것이 지원되는지 여부도 결정되지 않았기 때문에 더 논의하지 않았다. 그 결과 분산 캐시를 요구하는 고객은 WebSphere의 두 가지 분산 캐시 구현 중 하나인 hibernate.cache.provider_class 속성을 사용해 org.hibernate.cache.CacheProvider를 구현하는 클래스를 만들어야 한다.
  • 두 번째 수준 캐시 통합하기

    하이버네이트 세션은 작업의 유닛 범위를 대변한다. 세션 인터페이스는 하이버네이트 세션의 생명주기 동안 퍼시스턴스를 관리한다. 일반적으로 단일 스레드에서 가능한 인스턴스의 첫 번째 수준의 캐시를 가지는 매핑된 엔티티 클래스 인스턴스의 상태를 관리함으로써 이를 가능하게 한다. 작업 유닛(세션)이 완성되면 캐시는 없어진다. 두 번째 수준의 캐시 또한 클러스터 전반을 포함한 SessionFactory의 모든 세션 가운데 공유하도록 구성할 수 있다. 먼저 데이터베이스의 외부 변화나 클러스터 전반(클러스터 인식 캐시를 사용하지 않는 한) 모두에 있어 캐시를 일관성 있게 하기 위해 할 일은 없다. 둘째로 다른 레이어(데이터베이스 같은)는 이미 하이버네이트 캐시 값을 최소화하여 이미 캐시했다. 이 문제들은 애플리케이션 디자인에서 조심스럽게 고려돼야 하지만 이 글에서는 다루지 않겠다.

    하이버네이트는 미리 구성된 몇 가지 캐시를 갖는다. 이에 관한 정보는 하이버네이트 캐시 문서 페이지에서 찾을 수 있다. 읽기 전용 데이터에서 인-메모리 캐시 중 하나 정도로도 충분하다. 하지만 애플리케이션이 클러스터되고 클러스터 인식 캐시가 필요할 때 로컬 읽기 전용 캐시만으로는 충분하지 않다. 분산 캐시가 필요할 때 WebSphere가 제공하는 분산 캐시 구현 중 하나를 사용하기 바란다. 이들은 하이버네이트와 함께 2차 캐시로 사용될 것이다.

  • WebSphere Enterprise Service Bus와 WebSphere Process Server에서 하이버네이트 사용하기

    WebSphere Process Server와 ESB(WebSphere Enterprise Service Bus)는 SOA의 어셈블리와 프로그래밍 모델로 SCA(Service Component Architecture)와 SDO(Service Data Objects)에 의존한다(참고자료에서 SCA와 SDO에 대해 더 알아보자). SCA 컴포넌트는 자바 EE 컴포넌트가 아니므로 리소스 레퍼런스가 없지만 대신 서비스와 어댑터에 의존해 시스템에 연결한다. 자바 SCA 컴포넌트를 만들 때 리소스 레퍼런스를 사용할 수 없으므로 하이버네이트는 SCA 컴포넌트에 의해 직접 사용될 수 없다.

    이 경우, 하이버네이트 퍼시스턴스는 패사드(facade)에 나타나지 않아야 한다. 여기에는 두 가지 대안이 있다.

    • 하이버네이트 퍼시스턴스를 감싸기 위해 로컬 EJB 세션 패사드를 만든다. 세션 패사드는 어댑터 로직을 제공해 하이버네이트 엔티티 POJO와 Service Data Object 및 뒤를 매핑한다. 그러고 나면 통합 개발자는 EJB 임포트를 사용해 세션 패사드를 호출하며 QoS에 맞게 꽉 짜여진 한 쌍으로 호출한다.

    • 하이버네이트 퍼시스턴스를 감싸기 위해 EJB 웹 서비스 세션 패사드를 만든다. 그러고 나면 통합 개발자는 웹 서비스 임포트를 사용해 퍼시스턴스용 웹 서비스를 호출할 수 있다. 이를 위해 POJO에서 SDO로의 변환자를 만들어야 한다. 현재 SCA만이 데이터 유형용으로 SDO를 사용할 수 있기 때문이다. 그림 1은 프로세스에 관한 자세한 내용은 본 글에서 다루지 않지만 두 패턴 모두를 사용한 비즈니스 프로세스를 보여준다.



    그림 1. 샘플 비즈니스 프로세스
    그림 1. 샘플 비즈니스 프로세스

  • WebSphere Application Server V6.1 상의 하이버네이트 JPA API

    하이버네이트의 JPA 지원은 JPA 표준 퍼시스턴스를 제공하고 소유권 있는 하이버네이트 API를 대신할 수 있다. 하이버네이트의 JPA 구현은 자바 SE 5 기반의 런타임을 필요로 하므로 WebSphere Application Server V6.1 또는 그 이후 버전에서만 작동한다. 이 글을 출판하던 때 하이버네이트의 JPA 지원이 WebSphere System z나 iSeries 플랫폼에서 작동하지 않았다. 하이버네이트 문서는 하이버네이트의 JPA 구현을 사용해 패키지하는 방법과 애플리케이션을 배치하는 방법을 설명한다.

  • 상호운용성 없는/이식성 없는 기능

    JPA 명세의 3.2.4.2절은 상호운용성과 잠재적 이식성 문제를 불러올 만한 시나리오를 설명한다. 이는 지연 로딩(lazy loading, 즉 @Basic(fetch=LAZY)) 사용과 분리된 객체의 결합과 관련이 있다. 분리된 객체를 세션으로 다시 결합할 때 JPA가 객체를 검사하고 변경된 값을 가지는 데이터 저장을 업데이트할 것이다. 하지만 데이터 객체는 간단한 POJO다. POJO가 분리될 때 로드되지 않으면 다시 결합할 때 변경으로 나타날 것이다. 이를 제대로 작동하도록 하려면 업체는 자신의 런타임에 한정된 직렬화 기술을 구현해야 한다. 이는 상호운영적이지 않으며 시맨틱도 이식성이 없을 것이다.




위로


제품 및 고객 기술 지원

오픈 소스를 사용한 프로젝트 지원에 있어 고객들은 걱정을 하기 마련이고 업체에서 책임있는 지원을 해주느냐에 따라 사용에 영향을 미친다. IBM은 고객들이 IBM WebSphere Application Server와 IBM의 프레임워크가 아닌 다른 프레임워크를 결합해 사용하고자 한다는 것을 인식하고 IBM WebSphere Application Server용으로 가장 믿을 만한 운영 환경을 만들기 위해 노력했다. IBM은 애플리케이션의 한 부분으로 번들되거나 공유된 라이브러리이거나에 상관없이 오픈 소스 코드와 고객이 설치한 애플리케이션 프레임워크를 애플리케이션 코드의 일부로 생각한다. 오픈 소스 프로젝트를 사용할 때 이 정보를 조심스럽게 활용함으로써 고객들은 IBM 제품 및 기술 지원을 지속적으로 받으면서 IBM 제품을 계속 사용할 것이다. WebSphere 제품과 이 프레임워크들을 사용하면서 문제가 발생하면 IBM은 WebSphere 제품에 문제가 남지 않도록 적절한 노력을 할 것이다.

고객들이 이 글을 통해 제안사항을 받아들이고 몇 가지 주요 사항을 이해함으로써 IBM 제품에서 스프링이나 하이버네이트 같은 프레임워크를 안전히 사용하길 기대한다.

  • 고객들은 WebSphere Application Server가 허용하는 한에서 이 프레임워크들을 사용해야 한다. 더 구체적으로 말하자면 내부 제품 인터페이스에 이 프레임워크들을 사용해서는 안 된다는 뜻이다. 불행히도 많은 오픈 소스 프레임워크가 제대로 구성되지 않은 경우가 많다. 고객들은 WebSphere에서 피하라고 제안하는 것은 명백히 피해야 한다.

  • 오픈 소스 프레임워크에서 고객들은 WebSphere Application Server에서 사용하는 프레임워크용 소스코드와 바이너리를 이해하고 이에 접근해야 한다.

  • 고객들은 오픈 소스 커뮤니티나 오픈 소스 커뮤니티와 협업하는 파트너로부터 해당 프레임워크에 맞는 서비스를 받아야 한다.

IBM 지원 및 정책에 관한 더 자세한 내용은 IBM 지원 핸드북WebSphere Application Server 지원문을 참조하기 바란다.

이 글이 오픈 소스 환경에서 WebSphere Application Server를 사용할 때 독자들의 경험을 강화하는 데 도움이 된다 하더라도 WebSphere Application Server에 영향을 미치는 오픈 소스 컴포넌트나 다른 컴포넌트 관리의 모든 것을 다루지는 않는다. 오픈 소스 코드 사용자는 모든 컴포넌트의 명세를 확인하여 라이선스, 지원, 기술에 관련된 문제를 피해야 한다.

본 글에서 등장하는 "지원"이나 "지원된"이라는 용어는 IBM이 제공하는 기능에서만 사용됨에 주의하자. 필자들은 이 프레임워크들을 구성, 사용하는 방법에 대한 정보를 최선을 다해 제공해 사용이 문서화된 제품 행위에 일치하도록 했지만 이 문서는 스프링이나 하이버네이트의 보증서도, 지원문도 아니다.




위로


결론

스프링 프레임워크는 급속도로 인기를 얻고 있다. 개발자들은 J2EE 개발 시간과 쉬운 단위 테스팅을 가능하게 하는 쉬운 인터페이스와 XML 기반의 구성을 좋아한다. 프레임워크 자체도 매우 빨리 발전하여 이제 웹 사이트에 많은 하위 프로젝트를 나열한다. 모든 소프트웨어와 마찬가지로 결과적으로 애플리케이션에 어떤 혜택을 가져오는지 확인할 필요가 있으며 대안이 있다 하더라도 같은 결과를 가지는 더 선호하는 방법이 있을 수 있다. 물론 스프링 기능 중에 WebSphere Application Server 내에 이미 끼워진 기능을 복제하는 기능도 있을 것이므로 애플리케이션은 서버에 이를 배치하여 프레임워크 코드의 추가 레이어를 사용하지 않는 것이 좋다. 하지만 신중한 사용과 더불어 WebSphere Application Server의 폭발적이고 통합된 엔터프라이즈 지원 기능과 스프링이 가지는 쉽게 사용할 수 있는 많은 개발 기능을 함께 사용해 IBM의 업체 주도 J2EE 애플리케이션 서버에서 엔터프라이즈 애플리케이션을 신속히 개발, 배치할 수 있다.

하이버네이트는 WebSphere Application Server와 함께 성공적으로 사용해 관계형 데이터베이스에 저장된 엔티티 데이터에 객체-관계형 매핑을 제공하여 문제가 될 수 있는 시나리오를 피할 수 있도록 하는 몇 가지 퍼시스턴스 프레임워크 중 하나다. 특히 하이버네이트를 사용하는 데 내부 WebSphere Application Server 인터페이스를 사용해서는 안 된다. 이 글에서 권유하는 내용을 따라 일반적인 몇 가지 문제를 피할 수 있으며 WebSphere Application Server에 배치되는 애플리케이션용 퍼시스턴스 프레임워크로 하이버네이트를 사용할 수 있다.




위로


감사인사

이 글에 조언을 해 준 Keys Botzum, Paul Glezen, Thomas Sandwick, Bob Conyers, Neil Laraway, Lucas Partridge에게 감사한다.



참고자료



필자소개

Roland Barcia

Roland BarciaIBM Software Services for WebSphere의 IT 컨설팅 전문가며 IBM WebSphere: Deployment and Advanced Configuration의 공동 저자이기도 하다.


Tom Alcott은 미국 IBM의 IT 컨설팅 전문가이며 1998년 Worldwide WebSphere Technical Sales Support 팀이 생기면서부터 이 팀원으로 활동하고 있다. 여기서 그는 고객보다 한 발 앞서 생각하려고 노력하는 데 시간을 쏟고 있다. WebSphere 업무를 담당하기 전에는 TXSeries를 지원하는 IBM Transarc Lab의 시스템 엔지니어였다. 20년 넘게 메인프레임 기반 및 분산 시스템 모두에서 애플리케이션 디자인과 개발에 힘써왔고 WebSphere 런타임 이슈에 대한 글을 쓰고 발표를 해왔다.


Jim Knutson은 WebSphere의 J2EE 아키텍트다. J2EE 관련 명세의 IBM 참여를 담당하며 J2EE가 있기 전부터 이에 관여해 왔다. 또한 SOA와 웹 서비스를 지원하기 위한 프로그래밍 모델 전개에 참여하고 있다.


Sara Mitchell

Sara Mitchell은 IBM UK의 Hursley에 위치한 개발 연구소에서 WebSphere Application Server 개발팀장으로 일한다.


Ian Robinson

Dr. Ian Robinson은 IBM 선임 기술 스태프 멤버이자 IBM WebSphere Application Server 트랜잭션 아키텍트다. 12년 넘게 분산 트랜잭션 시스템 디자인과 구현을 담당해 왔고 IBM CICS 서버와 ComponentBroker COBRA 서버 작업을 해 왔다. OASIS 웹 서비스 트랜잭션 기술 위원회의 공동 의장이고 JSR 95(J2EE Activity Service)의 스펙 리더였으며 WS-트랜잭션 명세 모음의 공동 저자였다. 영국 University of Exeter에서 1986년에 물리학 학사를, 1989년에 물리학 박사 학위를 취득했다.


Author photo

Tim Ward는 IBM Hursley 연구소의 소프트웨어 엔지니어다. 애자일 프로젝트와 WebSphere Application Server 개발에 활발히 참여하고 있다. 영국 University of Cambridge에서 이론 물리학 분야의 Msci를 취득했다.




기사에 대한 평가


보다 나은 서비스를 제공하기 위함이오니 잠시 짬을 내어 이 양식을 제출하여 주십시오.



 


 


 


이 문서 북마킹 하기

mar.gar.in mar.gar.in naver naver eolin eolin del.icio.us del.icio.us





위로


developerWorks 콘텐트를 다른 사이트에 전재하기:
developerWorks 콘텐트에 대한 저작권은 IBM에 있습니다. IBM의 서면 허가나 원본 저자의 허락이 없이는 전재를 금합니다. 저희 콘텐트를 전재하시려면 IBM developerWorks 담당자 에게 문의하십시오.
    IBM 소개 개인정보 보호정책 문의