'JAVA/iBatis'에 해당되는 글 5건
- 2013.04.30 :: java.sql.SQLException: Already closed.
- 2009.07.08 :: ibator -_- 주석 제거
- 2009.05.18 :: iBatis에서 객체 매핑시 인스턴스 변수명 규칙?
- 2009.05.18 :: iBatis에서 insert후 자동 sequence Key 값을 가져오는 설정 방법
- 2009.05.14 :: iBATIS기초 - JNDI설정
error: java.sql.SQLException: Already closed. oracle
상황 : 이상없이 잘 사용하던 커넥션이 한번씩 끊긴다. 이후 재사용시에는 무리없는 활동을 보여준다.
이유 : 데이터베이스 입장에서 오랫동안 휴면되는 커넥션은 불필요하다고 판단하고, 끊어버린다. 때문에 커넥션풀 설정시 연결 확인용 쿼리를 지정해주어야 한다.
<property name="driverClassName" value="${db.driverName}"></property>
<property name="url" value="${db.url}"></property>
<property name="username" value="${db.username}"></property>
<property name="password" value="${db.password}"></property>
<property name="initialSize" value="${db.initialSize}"></property>
<property name="maxActive" value="${db.maxActive}"></property>
<property name="validationQuery" value="select 1 from dual" /> <—Oracle
<property name="validationQuery" value="select 1" /> <-- MySql -->
DEBUG: org.springframework.jdbc.datasource.DataSourceUtils - Could not close JDBC Connection
java.sql.SQLException: Already closed.
at org.apache.commons.dbcp.PoolableConnection.close(PoolableConnection.java:114)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.close(PoolingDataSource.java:191)
at org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:333)
at org.springframework.jdbc.datasource.DataSourceUtils.releaseConnection(DataSourceUtils.java:294)
at org.mybatis.spring.transaction.SpringManagedTransaction.close(SpringManagedTransaction.java:122)
at org.apache.ibatis.executor.BaseExecutor.close(BaseExecutor.java:78)
at org.apache.ibatis.executor.CachingExecutor.close(CachingExecutor.java:65)
at org.apache.ibatis.session.defaults.DefaultSqlSession.close(DefaultSqlSession.java:206)
at org.mybatis.spring.SqlSessionUtils.closeSqlSession(SqlSessionUtils.java:172)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:371)
at $Proxy15.selectList(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:194)
at kr.faz.ordersheet.dao.impl.OrdersheetDaoImpl.list(OrdersheetDaoImpl.java:26)
at kr.faz.ordersheet.service.impl.OrdersheetServiceImpl.list(OrdersheetServiceImpl.java:27)
at kr.faz.ordersheet.controller.OrdersheetController.checkData(OrdersheetController.java:110)
at kr.faz.ordersheet.controller.OrdersheetController.adminOrdersheetList(OrdersheetController.java:74)
at kr.faz.ordersheet.controller.OrdersheetController$$FastClassByCGLIB$$86da2af8.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80)
at kr.faz.aop.SessionCheck.adminSessionCheck(SessionCheck.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
at kr.faz.ordersheet.controller.OrdersheetController$$EnhancerByCGLIB$$8d2c0c1.adminOrdersheetList(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:852)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:584)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1508)
at java.lang.Thread.run(Thread.java:619)
org.springframework.dao.DataAccessResourceFailureException:
### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
### The error may exist in file [P:\WSC\sts\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\cs\WEB-INF\classes\mybatis\xml\ordersheet.xml]
### The error may involve SqlOrdersheetMapper.ordersheetList
### The error occurred while executing a query
### SQL: SELECT ************** LIMIT ? , ?
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
; SQL []; No operations allowed after connection closed.; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:91)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:71)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:364)
at $Proxy15.selectList(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:194)
at kr.faz.ordersheet.dao.impl.OrdersheetDaoImpl.list(OrdersheetDaoImpl.java:26)
at kr.faz.ordersheet.service.impl.OrdersheetServiceImpl.list(OrdersheetServiceImpl.java:27)
at kr.faz.ordersheet.controller.OrdersheetController.checkData(OrdersheetController.java:110)
at kr.faz.ordersheet.controller.OrdersheetController.adminOrdersheetList(OrdersheetController.java:74)
at kr.faz.ordersheet.controller.OrdersheetController$$FastClassByCGLIB$$86da2af8.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80)
at kr.faz.aop.SessionCheck.adminSessionCheck(SessionCheck.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
at kr.faz.ordersheet.controller.OrdersheetController$$EnhancerByCGLIB$$8d2c0c1.adminOrdersheetList(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:852)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:584)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1508)
at java.lang.Thread.run(Thread.java:619)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920)
at com.mysql.jdbc.ConnectionImpl.throwConnectionClosedException(ConnectionImpl.java:1304)
at com.mysql.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.java:1296)
at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4511)
at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4476)
at org.apache.commons.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:281)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.prepareStatement(PoolingDataSource.java:313)
at sun.reflect.GeneratedMethodAccessor31.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.ibatis.logging.jdbc.ConnectionLogger.invoke(ConnectionLogger.java:52)
at $Proxy16.prepareStatement(Unknown Source)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.instantiateStatement(PreparedStatementHandler.java:72)
at org.apache.ibatis.executor.statement.BaseStatementHandler.prepare(BaseStatementHandler.java:82)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.prepare(RoutingStatementHandler.java:54)
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:70)
at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:56)
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:259)
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:132)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:105)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:81)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:104)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:98)
at sun.reflect.GeneratedMethodAccessor125.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:354)
... 56 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 101,739 milliseconds ago. The last packet sent successfully to the server was 101,739 milliseconds ago.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1121)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3871)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2484)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2809)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2758)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1612)
at com.mysql.jdbc.DatabaseMetaData.getUserName(DatabaseMetaData.java:6791)
at org.apache.commons.dbcp.DelegatingConnection.toString(DelegatingConnection.java:123)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.toString(PoolingDataSource.java:355)
at java.lang.String.valueOf(String.java:2827)
at java.lang.StringBuilder.append(StringBuilder.java:115)
at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:85)
at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:66)
at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:271)
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:69)
... 67 more
Caused by: java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3852)
... 81 more
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class CommentClean {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
StringBuffer sb = new StringBuffer();
File newFile = new File( "파일절대경로");
if (newFile.exists()) {
FileReader fr = new FileReader(newFile);
BufferedReader br = new BufferedReader(fr);
String readData = br.readLine();
while (readData != null) {
sb.append(readData);
readData = br.readLine();
}
int start = 0, end=0;
while(true){
start = sb.indexOf("/**");
end = sb.indexOf("*/");
// System.out.println("start : " + start);
// System.out.println("end : " + end);
if (start == -1 || end == -1 )
break;
sb.replace(start ,end+2, "");
start =0;
end = 0;
}
System.out.println(sb.toString().replaceAll("}", "}\n").replaceAll(";", ";\n").replaceAll("\\{", "\\{\n"));
br.close();
fr.close();
} else {
System.out.println("파일이 업네여....");
}
}
}
<select id="getContent" parameterClass="int" resultClass="content">
<![CDATA[
SELECT
SEQ_ID
, CREATED_DATE
, TITLE
, CONTENT
, CONTENT_TYPE
FROM CONTENT
WHERE SEQ_ID=#id#
]]>
</select>
</sqlMap>
객체의 인스턴스 변수를 다음과 같이 했습니다.
private String createdDate;
private String title;
private String content;
private String contentType;
TABLE 'CONTENT'에는 다음과 같이 DATA가 존재합니다.
Query를 수행 한 결과 log가 다음과 같았습니다.
[COTAMOT] INFO,[2008-02-13 10:29:57,546],[main],(IBatisDaoTest.java:40),#### CREATE_DATE : null
[COTAMOT] INFO,[2008-02-13 10:29:57,636],[main],(IBatisDaoTest.java:41),#### TITLE : 첫번째 글
[COTAMOT] INFO,[2008-02-13 10:29:57,636],[main],(IBatisDaoTest.java:42),#### CONTENT : 첫번째 글 내용입니다.
[COTAMOT] INFO,[2008-02-13 10:29:57,636],[main],(IBatisDaoTest.java:43),#### TYPE : null
네이밍 규칙에 맞지 않은듯 합니다. '_'를 쓰지 않은 'TITLE', 'CONTENT'는 올바르게 담아오지만 그 외의 것은 값을 가져오지 못했습니다. Query문을 다음과 같이 변경하였습니다.
<select id="getContent" parameterClass="int" resultClass="content">
<![CDATA[
SELECT
SEQ_ID as seqId
, CREATED_DATE as createdDate
, TITLE as title
, CONTENT as content
, CONTENT_TYPE as contentType
FROM CONTENT
WHERE SEQ_ID=#id#
]]>
</select>
</sqlMap>
결과는 다음과 같습니다.
[COTAMOT] INFO,[2008-02-13 10:51:39,999],[main],(IBatisDaoTest.java:40),#### CREATE_DATE : 2008-02-12
[COTAMOT] INFO,[2008-02-13 10:51:39,999],[main],(IBatisDaoTest.java:41),#### TITLE : 첫번째 글
[COTAMOT] INFO,[2008-02-13 10:51:39,999],[main],(IBatisDaoTest.java:42),#### CONTENT : 첫번째 글 내용입니다.
[COTAMOT] INFO,[2008-02-13 10:51:40,009],[main],(IBatisDaoTest.java:43),#### TYPE : NN
Query문에서 각 column을 alias로 해서 인스턴스 변수와 일치시켰더니 데이터를 올바르게 가져옵니다. 자바의 기본 네이밍 규칙이 먹히지 않는 것일까요? 찾아봐야 겠습니다. 또한 resultClass를 사용하면 자동을 mapping 해서 좋은데 그 만큼 부하가 걸리기 때문에 resultMap을 사용하는 것이 더 좋다는 얘기도 있습니다. 올바를 사용법을 알아야 겠습니다.
이 경우 Insert 행위시에 parent에 대해서 child도 함께 Insert 된다고 가정하겠습니다. 이럴 경우 parent를 Insert처리하고 Select를 던져서 해당 key정보를 얻어야 child를 Insert할 수 있습니다. 이럴 경우 iBatis에서 설정하는 방법을 알아보겠습니다.
sqlMap xml설정을 다음과 같합니다.
<![CDATA[
INSERT INTO CONTENT (
CREATED_DATE, TITLE, CONTENT, CONTENT_TYPE
) VALUES (
now(), #title#, #content#, #contentType#
)
]]>
<selectKey keyProperty="seqId" resultClass="int">
SELECT LAST_INSERT_ID()
</selectKey>
</insert>
위와 같이 설정하고 소스부분에서 다음과 같이 작성합니다.
content.setTitle("selectKey 테스트");
content.setContent("<selectKey.../>에 대하여 테스트 합니다.");
content.setContentType("NN");
Integer seqId = contentService.insertContent(content);
이 결과는 Integer Type의 객체로 Insert된 sequence Key 값을 가져옵니다.
위 설정에서 <selectKey keyProperty="seqId" resultClass="int"> 부분을 살펴 보면 seqId는 Content 객체의 Integer Type의 인스턴스 변수입니다. native Type (int)으로 해도 문제가 발생하지 않는 것으로 알고 있습니다. 소스 부분에서
Integer seqId = contentService.insertContent(content);
이 부분에서 반드시 Integer Type으로 받아야 합니다. 그렇지 않으면 CastingException이 발생하게 됩니다. (native Type int로 받아도 문제 없습니다^^)
수행된 log를 출력하면 다음과 같습니다.
[COTAMOT] DEBUG,[2008-02-14 16:44:52,136],[main],(JakartaCommonsLoggingImpl.java:27),{pstm-100001} Executing Statement:
INSERT INTO CONTENT (
CREATED_DATE, TITLE, CONTENT, CONTENT_TYPE
) VALUES (
now(), 'selectKey 테스트', '<selectKey.../>에 대하여 테스트 합니다.', 'NN'
)
[COTAMOT] DEBUG,[2008-02-14 16:44:52,346],[main],(JakartaCommonsLoggingImpl.java:27),{pstm-100002} Executing Statement:
SELECT LAST_INSERT_ID()
Insert가 수행되고 다음에 Select 가 수행됨을 알수 있습니다.
참고로 sequence 값을 가져오는 방법을 DBMS별로 나열하면 다음과 같습니다.
mssql - SCOPE_IDENTITY()
mysql - LAST_INSERT_ID()
이렇게 되면 child를 Insert 처리 할 때 FK 값을 얻는데 간편합니다.
<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<settings
cacheModelsEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="true"
maxRequests="50"
maxSessions="25"
maxTransactions="10"
useStatementNamespaces="false"
/>
<!--Type aliases allow you to use a shorter name for long fully qualified class names. -->
<typeAlias alias="order" type="testdomain.Order"/>
<!-- Configure a built-in transaction manager. If you're using an
app server, you probably want to use its transaction manager
and a managed datasource -->
<transactionManager type="JDBC" commitRequired="false">
<dataSource type="JNDI">
<property name="DataSource" value="java:/comp/env/jdbc/DB"/>
</dataSource>
</transactionManager>
<!--sqlMap resource="C:\LuckyData\Project\Java1.5\data\ibatis\Member.xml"/-->
<sqlMap resource="board/board.xml"/>
<sqlMap resource="login/login.xml"/>
<sqlMap resource="db/dbChange.xml"/>
<sqlMap resource="statics/static.xml"/>
<!-- List more here...
<sqlMap resource="com/mydomain/data/Order.xml"/>
<sqlMap resource="com/mydomain/data/Documents.xml"/>
-->
</sqlMapConfig>
빨간색 부분처럼 바꿔준다. JNDI 물론 톰캣 SERVER.XML에 설정이 되있어야 겠다.
SERVER.XML
<Resource name="jdbc/IMARC" auth="Container" type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@XXX.XXX.XXX.X:XXX:XXXX"
username="XXXX" password="XXXX maxActive="20" maxIdle="10" maxWait="10000" />
</Context>
각자설정에 알맞게 바꿔야겠죠?^^
출처 : http://matz.egloos.com/1442344