Spring - myBatis 환경에서 트랜잭션이 적용되지 않으면 아래 로그를 볼 수 있다.

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1ad7d61e] was not registered for synchronization because synchronization is not active
Fetching JDBC Connection from DataSource
trace com.mchange.v2.resourcepool.BasicResourcePool@723b12e9 [managed: 20, unused: 19, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@6f25ab49)
JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@5beadc25] will not be managed by Spring
==>  Preparing: UPDATE iot.user SET user_name = ?, nickname = ?, email = ?, is_admin = ?, update_date = NOW() WHERE seq = ?
==> Parameters: Test46(String), Test?46(String), 12@abc.com(String), 0(String), 346(Integer)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1ad7d61e]
Returning JDBC Connection to DataSource


-- applicationContext-beans.xml
<!-- Annotation 기반의 Component Scan 필터(service package 만 검색) -->
<context:component-scan base-package="com.iot.pf">
      <context:include-filter type="regex" expression="\.*\.service\.*" />
</context:component-scan>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
       <!-- DB에 접속 하기 위해서 설정 -->
      <property name="dataSource" ref="dataSource" />   
      
      <!-- myBatis 기본 설정 -->
      <property name="configLocation" value="classpath:mybatis-configuration.xml" />
      
      <!-- query 적힌 xml 위치 -->
      <property name="mapperLocations" value="classpath:sql/SQL.*.xml" />
      <!-- 트랜잭션 관리를 위한 것 -->
      <property name="transactionFactory">
           <bean class="org.mybatis.spring.transaction.SpringManagedTransactionFactory" />
      </property>
</bean>

<!-- DAO(interface) 위치를 basePackage로.. -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
      <property name="basePackage" value="com.iot.pf.dao" />
</bean>

<!-- 트랜잭션 관리를 위한 bean  -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource" />
</bean>

-- servlet.xml

<context:component-scan base-package="com.iot.pf" use-default-filters="false" >
      <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
      <context:include-filter type="annotation" expression="org.springframework.stereotype.Component" />
</context:component-scan>

<!-- File Upload -->
      <property name="maxUploadSize" value="50000000" />
</bean>

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="prefix" value="/WEB-INF/views/"/>
      <property name="suffix" value=".jsp"/>
</bean>

<mvc:resources mapping="/resources/**" location="/resources/" />

<mvc:annotation-driven />

<!-- transaction annotation -->
<tx:annotation-driven transaction-manager="transactionManager"/>

-- service file
@Service("userService")
@Transactional(rollbackFor = {Exception.class})
public class UserServiceImpl implements UserService{
 
}


트랜잭션이 적용되면 아래 로그를 볼 수 있다.
Creating new transaction with name [com.iot.pf.service.impl.UserServiceImpl.update]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '',-com.iot.pf.exception.AnomalyException,-java.lang.Exception
trace com.mchange.v2.resourcepool.BasicResourcePool@63cfcf47 [managed: 20, unused: 19, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@3f24eec6)
Acquired Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@19668759] for JDBC transaction
Switching JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@19668759] to manual commit
Getting transaction for [com.iot.pf.service.impl.UserServiceImpl.update]
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5c640a11]
JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@19668759] will be managed by Spring
==>  Preparing: UPDATE iot.user SET user_name = ?, nickname = ?, email = ?, is_admin = ?, update_date = NOW() WHERE seq = ?
==> Parameters: Test46(String), Test46(String), 123@abc.com(String), 0(String), 346(Integer)
<==    Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5c640a11]
Completing transaction for [com.iot.pf.service.impl.UserServiceImpl.update] after exception: com.iot.pf.exception.AnomalyException: You have an anomaly result value after [INSERT/UPDATE/DELETE] query!!!!
Applying rules to determine whether transaction should rollback on com.iot.pf.exception.AnomalyException: You have an anomaly result value after [INSERT/UPDATE/DELETE] query!!!!
Winning rollback rule is: RollbackRuleAttribute with pattern [com.iot.pf.exception.AnomalyException]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5c640a11]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5c640a11]
Initiating transaction rollback
Rolling back JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@19668759]
Releasing JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@19668759] after transaction
Returning JDBC Connection to DataSource




java.lang.AbstractMethodError: Method com/mchange/v2/c3p0/impl/NewProxyPreparedStatement.isClosed()Z is abstract

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.2</version>
</dependency>

위 처럼 mybatis 3.4.6, mybatis-spring 버전을 1.3.2로 사용하고 테스트를 하니 위 에러가 나더라..


<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.2</version>
</dependency>

c3p0 라이브러리 버전이 낮아서 그런거 이므로 최신 버전으로 바꾸어 사용하면 된다.



Mapper 방식은 아래 처럼 사용한다.
	
	    
	    
	


pacakge com.openerp.dao

public interface RoleDao{
	List listRole(Parameters params);
	List listRole(Parameters params, int pg, int ps);
}

이 경우 Mapper에 등록을 했기때문에 roleMapper 라는 이름으로  bean에 등록이 된다.

"예전부터 사용해오던 DAO 패턴을 같이 쓸 수 없을까?" 라는 궁금증이 생겨 반나절동안 해 보았는데... 안된다.

DAO 패턴도 어쨋든 Spring DI에 등록이 되어야 하는데 같은 클래스가 두개의 이름으로 등록이 되는 현상이 발생된다. 

No qualifying bean of type [com.openerp.dao.RoleDao] is defined: expected single matching bean but found 2: roleDao,roleMapper


이 같은 결론을 얻고 생각을 해보니.. 

DAO Pattern을 그냥 간소화 시켜서 사용하는게 Mapper 방식이네? 


reference)
myBatis DAO Pattern example : http://blog.idleworx.com/2011/09/mybatis-dao-example-code-tutorial.html 

	
	   
	    	{	CALL LOMS_APP.PRC_CLEAN_ATTRES(?, ?, ?)	}

	

{ 와 CALL 사이에... tab (\t)가 들어 있는데 오류 난다... 헐...
	
	    
	    	{CALL PRC_CLEAN_ATTEND(?, ?, ?)}
	    
	










  top_vacancy = 'Y',

'백엔드 > myBatis' 카테고리의 다른 글

MyBatis 3.2) Mapper 방식과 DAO Pattern은 같이 사용할 수 없다.  (0) 2013.07.19
프로시저 호출 시 주의 할 점..  (0) 2012.11.13
iBatis isEqual  (0) 2012.11.05
[3.0] forEach 사용  (0) 2010.07.15
[3.0] like 검색.  (0) 2010.07.09
[3.0] JDBC Type  (0) 2010.07.09
  • item : forEach내에서 각 아이템 이름으로 사용할 것.
  • index : index
  • collection="classNames"  // 배열명
  • open=""  // forEach 시작 전 ex: "(" forEach 시작전에 ( #{item}
  • separator=","  // forEach 1회시 구분 해줄 기호
  • close="" // forEach 종료 후 ex: ")" forEach 종료 후에 ( #{item}, #{item}, #{item} .... #{item[index]} )



  
	SUM(CASE WHEN R.CLASS_NAME = #{item}  THEN R.CNT ELSE 0 END) AS #{item}



'백엔드 > myBatis' 카테고리의 다른 글

프로시저 호출 시 주의 할 점..  (0) 2012.11.13
iBatis isEqual  (0) 2012.11.05
[3.0] forEach 사용  (0) 2010.07.15
[3.0] like 검색.  (0) 2010.07.09
[3.0] JDBC Type  (0) 2010.07.09
iBatis 3.0 Cache 문제 -  (0) 2010.07.08
- iBatis 3.0 에서 간단하게 like 검색 하는 법

CB.CUSTOMER_NAME like CONCAT('%', #{customerName:VARCHAR}, '%')

사용 예 )
<-select id="expired_search" parametertype="java.util.HashMap" resulttype="net.autobrain.domain.ExpiredSearchResult" flushcache="false" usecache="false">
SELECT CB.COUPON_BOOK_NO, CN.COUPON_NAME_SEQ, CN.COUPON_NAME
		    , CASE WHEN CB.CHARGE_TYPE = 'F' THEN '무상' ELSE '유상' END AS CHARGE_TYPE
		    , AM.AUTO_MODEL_SEQ
		    , AM.MODEL_NAME
		    , IFNULL(CB.CAR_NUMBER, '') AS CAR_NUMBER
		    , CB.VIN_NO
		    , CB.CUSTOMER_NAME
		    , CONCAT(CB.CUSTOMER_PHONE_1, '-', CB.CUSTOMER_PHONE_2, '-', CB.CUSTOMER_PHONE_3) AS CUSTOMER_PHONE
		    , CB.AUTO_SALES_USER_SEQ
		    , SU.USER_NAME
		    , CB.COUPON_EXPIRED_DATE
		FROM COUPON_BOOK CB
		    INNER JOIN COUPON CP ON CP.COUPON_BOOK_SEQ = CB.COUPON_BOOK_SEQ
		    INNER JOIN COUPON_BOOK_SETUP CBS ON CBS.COUPON_BOOK_SETUP_SEQ = CB.COUPON_BOOK_SETUP_SEQ
		    INNER JOIN COUPON_NAME CN ON CN.COUPON_NAME_SEQ = CBS.COUPON_NAME_SEQ
		    INNER JOIN COUPON_SETUP CS ON CBS.COUPON_BOOK_SETUP_SEQ = CS.COUPON_BOOK_SETUP_SEQ
		    INNER JOIN AUTO_MODELS AM ON CBS.AUTO_MODEL_SEQ = AM.AUTO_MODEL_SEQ
		    INNER JOIN AUTO_CLASSES AC ON AM.AUTO_CLASS_SEQ AND AC.AUTO_CLASS_SEQ
		    INNER JOIN SALES_USERS SU ON SU.SALES_USER_SEQ = CB.AUTO_SALES_USER_SEQ
		    INNER JOIN SHOWROOM_CODES SC ON SU.SHOWROOM_SEQ = SC.SHOWROOM_SEQ
		WHERE CB.REFUND_DATE IS NULL AND CB.DISABLE IS NULL
		AND CN.COUPON_NAME_SEQ = #{couponNameSeq}
		AND CB.CUSTOMER_NAME like CONCAT('%', #{customerName:VARCHAR}, '%')
	        AND DATE_FORMAT(#{beginCriterionDate}, '%Y-%m-%d') <= DATE_FORMAT(DATE_SUB(CB.COUPON_EXPIRED_DATE, INTERVAL #{gubun} DAY), '%Y-%m-%d')
		AND DATE_FORMAT(DATE_SUB(CB.COUPON_EXPIRED_DATE, INTERVAL #{gubun} DAY), '%Y-%m-%d') <= DATE_FORMAT(#{endCriterionDate}, '%Y-%m-%d')
		AND (TO_DAYS(CB.COUPON_EXPIRED_DATE) - TO_DAYS(CAST(#{criterionDate} AS DATE)) BETWEEN #{criterionDay1:NUMERIC} AND #{criterionDay2:NUMERIC})
		GROUP BY COUPON_BOOK_NO
    <-/select>

'백엔드 > myBatis' 카테고리의 다른 글

프로시저 호출 시 주의 할 점..  (0) 2012.11.13
iBatis isEqual  (0) 2012.11.05
[3.0] forEach 사용  (0) 2010.07.15
[3.0] like 검색.  (0) 2010.07.09
[3.0] JDBC Type  (0) 2010.07.09
iBatis 3.0 Cache 문제 -  (0) 2010.07.08

쿼리~~
AND (TO_DAYS(CB.COUPON_EXPIRED_DATE) - TO_DAYS(CAST(#{criterionDate} AS DATE)) BETWEEN #{criterionDay1:NUMERIC} AND #{criterionDay2:NUMERIC})


'백엔드 > myBatis' 카테고리의 다른 글

프로시저 호출 시 주의 할 점..  (0) 2012.11.13
iBatis isEqual  (0) 2012.11.05
[3.0] forEach 사용  (0) 2010.07.15
[3.0] like 검색.  (0) 2010.07.09
[3.0] JDBC Type  (0) 2010.07.09
iBatis 3.0 Cache 문제 -  (0) 2010.07.08

1. Query 실행 후 그 결과를 Map에 담아 리턴해 페이지에 출력.
2. 다른 곳에서 위 출력 결과에 영향을 주는 컬럼 값을 변경한다. 
3. 다시 1번을 수행하면 2번의 결과가 반영되지 않고 수정하기 전의 결과가 딱 나온다.

iBatis로그가 아닌 일반 로그에서는 호출은 되나 iBatis가 실행되진 않았다.

- 조건을 다르게 해서 실행 했을경우 sql을 실행하지만, 결과 값인 Map에는 수정하기 전의 정보가 들어있다.
- statementType="CALLABLE" flushCache="false" useCache="false" 모두 헛 수고

왜 그런지 문서좀 뒤져야겠다..

일단.. iBatis 로그부터 찍어야하고..

'백엔드 > myBatis' 카테고리의 다른 글

프로시저 호출 시 주의 할 점..  (0) 2012.11.13
iBatis isEqual  (0) 2012.11.05
[3.0] forEach 사용  (0) 2010.07.15
[3.0] like 검색.  (0) 2010.07.09
[3.0] JDBC Type  (0) 2010.07.09
iBatis 3.0 Cache 문제 -  (0) 2010.07.08

+ Recent posts