이 에러 발생시 Oracle JDBC Driver를 업데이트 해준다.

가령.. 11g 기준의 jar 파일이러단가..

JDK6을 지원하는 ojdbc6.jar로 교체하면 정상 작동한다. 
원글 : http://techblog.bozho.net/?p=358)**

이 글을 Korea Spring User Group의 송준이 <socurites@gmail.com>  님이 번역을 하여 글을 퍼옵니다.


 *지독하게 해로운 프레임워크, 그리고 복잡함*
     
    *(*http://techblog.bozho.net/?p=358)**
     
    2011년 4월 29일
      
    하이버네이트와 스프링같은 프레임어크는 업계 표준이다. JSF, EJB 등도 또한 업계 표준으로 많은 어플리케이션에 사용된다. 하지만
    프레임워크 사용을 반대하는 사람들은 항시 있기 마련이다. 다루려는 주제는 "언어 불가지론(language-agnostic)"에 대한
    것이고 자바를 예로 들겠지만, 모든 언어에 적용되는 내용이다.
     
     
    프레임워크를 반대하는 일반적인 근거는 다음과 같다.
     
    - 프레임워크는 매우 복잡하고, 사용할 필요가 없다
     
    - 더 효과적인 프레임워크를 직접 만들 수 있다.
     
    - 프레임워크가 품질이 높을 것 같지 않으며, 필요한 작업을 해줄 것 같지도 않다.
     
    - 프레임워크를 추가적으로 배울 필요가 없으며, 코어 자바로도 충분하다.
     
    - "프레임워크가 그렇게도 좋아?"라는 말을 한번도 들어본적이 없다.
     
      
    안타까운 점은 이렇게 믿는 사람들과 말이 통하지 않는다는 점이다. 게다가 이 부류의 사람들이 프로젝트를 이끄는 리더거나 아키텍트가
    되버리면, 결국 프로젝트는 망한다. 그래도 오해는 하지 말기 바란다. 이들 프레임워크를 사용하지 않고도 성공하는 프로젝트도 꽤 있다. 하지만
    이 프로젝트들은 일반적인 경우는 아니다. 위의 논거들을 조목조목 다뤄보도록 하자.
     
     
    "프레임워크는 매우 복잡하고, 사용할 필요가 없다" - 복잡도는 사실 프레임워크에서 나타나는 문제점이다. 프레임워크를 처음 익힐 때는
    일주일이 걸린다. 하지만 시작할 때만 어려울 뿐이고, 한번 익히고 나면 팀은 프레임워크를 능숙하게 다룰 수 있게 된다. 결국 특정
    수준정도로 어려울 뿐이다. 내 경험을 빌려 이 점을 확실히 알 수 있다. 지금 일하는 회사에 왔을 때, 회사에서는 스프링과 하이버네이트를
    사용해 대규모의 프로젝트를 진행하고 있었다. 일주일 가량 지나자 나는 이 프로젝트에서 무엇이든 변경할 수 있게 되었다. 스프링을 적용한
    프로젝트는 복잡도가 증가하는 게 아니라 그저 규모가 커질 뿐이고, 복잡도는 특정 수준에 그칠 뿐이다. 이 복잡도는 알고리즘에 관련된게
    아니라, 구조와 설정에 관련된다.
     
      
    다음으로 "더 효과적인 프레임워크를 직접 만들 수 있다"는 주장이 가진 문제점을 살펴보자. 프레임워크를 직접 만들게되면, 복잡도는 한없이
    증가하기 쉽다. 항상 그렇지는 않지만, 직접 프레임워크를 만들고 바귀를 다시 발명하게 되면 프로젝트를 유지하기에 어려울 때가 많다.
     
      
    일하는 팀이 5명내지 6명으로 구성되고, 팀원은 비즈니스 가치를 이끌어내야지 프레임워크를 작성할 시간이 부족하다는 점은 말할 필요도 없다.
    오픈소스 프레임워크에 수천 시간을 들이고, 이 프레임워크를 개발하고 생길 수 있는 모든 종류의 이슈와 문제점을 찾느라 수백만 시간을
    들였다는 점을 생각해볼 때, "프레임워크가 품질이 높을 것 같지 않으며, 필요한 작업을 해줄 것 같지도 않다"는 주장은 근거가 없어
    보인다. 널리 쓰이는 프레임워크는 평범한 팀에서 프로젝트 일정에 맞춰서 만들 수 있는 프레임워크이 비해 품질이 훨씬 높다.
     
     
     하지만 다른 방향에서 접근하는 사람들도 있기 마련인데, 바로 "과도한 설계'다. 내 생각에 과도한 설계는 프로젝트에서 있을 수 있는 가장
    큰 문제다. 그리고 "프레임워크를 추가적으로 배울 필요가 없으며, 코어 자바로도 충분하다"는 근거가 요점을 제대로 짚은 것처럼 보인다. 하지만
    이 주장은 "능력이 부족하거나 배울 실력이 안되며 배우고자하는 의지가 없다"는 말을 속여서 말한 것에 지나지 않는다. 나는 프레임워크에
    대해 불평하는 일(stackoverflow.com에 있는 질문들을 포함해)을 많이 봐왔다. 스프링은 쓸데 없이 복잡하고
    비대해졌으며, 하이버네이트는
    제어권을 개발자로부터 빼았고, 문제점들을 많이 만들어낸다는 것이다. 왜 이들 주장이 확실히 잘못된 것인지는 설명하지 않겠다. 하지만
    사람들이 이들 프레임워크를 잘 이해하지 못했기에 이처럼 주장하는 것이다. 그리고 겉보기에 더 쉬운 방법을 선택하게 되면 결국 실망만
    가져올 뿐이다.
      
     
    반대로 잘 알지도 못하면서 프레임워크가 유행하기 때문에 도입하려는 사람들도 있다. 결국 이들은 프레임워크를 비난하게 된다. 이들 사이에
    공통적인 테마가 있음을 알 수 있다. 문제는 프레임워크가 아니라, 프레임워크를 이해하지 못하는 사람이다.
      
     
    그렇긴 해도 프레림워크는 모두 훌륭하다는 뜻은 아니다. EJB2는 별로였다. 스트럿츠 1도 벼로였다. 하지만 프레임워크를 비난한 입장이
    되려면 진짜 문제가 무엇인지 그리고 어떻게 고쳐야 하는지 알아야만 한다. 개빈 킹과 로드 존슨은 깨달았다. 다른 이들은 EJB 2를
    사용했고, 이는 "아마도" 직접 만든 프레임워크를 사용한 것이 비하면 더 나은 선택이었을 것이다. 뭐 당신이 수퍼 아키텍트라서 직접 만든
    프레임워크가 더 낫다고 치자. 그렇다면, 스프링/하이버네이드/기타 등등의 프레임워크를 압도하는 사이트의 링크를 부담 갖지 말고 알려주기
    바란다.
     
      
    이렇게까지 말하고 나면 "프레임워크 반대론자"는 "도대체 왜 새롭게 나오는 프레임워크들을 모두 배워야 하지"라고 악을 쓸수 있다. 먼저,
    배운만큼 얻기 마련인데, 어쨌든 새로운 것을 매일 익혀야하기 때문이다. 두번째로는 인기 있는 프레임워크는 최선의 방법과 개념들을 보급하기
    때문이다. 프레임워크 통해 흔히 생기는 상황에 대처하는 최선의 방법을 배울 수 있다. 또 다른 장점으로 스프링에 정통해지면 다른 의존성
    주입을 활용하는 프레임워크를 쉽게 배울 수 있으며, 하이버네이트 전문가가 되면 어떤 ORM도(실제로는 객체를 객체지향이 아닌
    데이터에비스에 매핑하는 어떤 툴도(NoSQL을 포함해)) 쉽게 배울 수 있다. 다시 말하면, 설정 방법과 메서드 사용법이 문서화되어 있고,
    쉽게 확인할 수 있다. 프레임워크에서 중요한 건 바로 개념이다.
      
     
    따라서 중요한 것은 프레임워크를 도입할 지, 장단점을 제대로 평가할 수 있을지, 그리고 당면한 프로젝트에 적합한지 선택하는 사람들의
    능력과 이해 정도다. 프레임워크는 수월하게 개발하기 위해 만들여졌지, 복잡하게 만들려고 만들어진게 아니다. 시작할 때는 어려움이 따르지만,
    프레임워크를 제대로 선택했다면 이후로는 복잡도를 생각하는 것보다는 낮은 수준으로 맞출 수 있다.



아주 좋은 글이다.

     


왜 제네릭이 안되었는지 이제 알았다. 확실히...

먼저 제네릭이 안되었을때의 하이버네이트와 매핑한 bean을 살펴보면

 @Id
 @GeneratedValue(strategy=GenerationType.AUTO)
 public Integer getUserSeq() {
     return userSeq;
 }

오류난 로그

2010-01-09 23:06 [DEBUG] opened session at timestamp: 12630460153
2010-01-09 23:06 [DEBUG] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
2010-01-09 23:06 [DEBUG] opening JDBC connection
2010-01-09 23:06 [DEBUG] select this_.userSeq as userSeq2_0_, this_.ANSWER as ANSWER2_0_, this_.BIRTH_DAY as BIRTH3_2_0_, this_.CREATE_DATE as CREATE4_2_0_, this_.DISABLE as DISABLE2_0_, this_.DOMAIN as DOMAIN2_0_, this_.E_MAIL as E7_2_0_, this_.EMAIL_DENY as EMAIL8_2_0_, this_.masterCodes as masterCo9_2_0_, this_.QUESTION as QUESTION2_0_, this_.RELATION_GROUP_SEQ as RELATION11_2_0_, this_.RELATION_SEQ as RELATION12_2_0_, this_.UPDATE_DATE as UPDATE13_2_0_, this_.USER_ID as USER14_2_0_, this_.USER_NAME as USER15_2_0_, this_.USER_NICK as USER16_2_0_, this_.USER_PW as USER17_2_0_, this_.USER_STATUS as USER18_2_0_ from MEMBER this_ where this_.USER_ID=? and this_.USER_PW=?
2010-01-09 23:06 [DEBUG] preparing statement
2010-01-09 23:06 [DEBUG] binding 'agnes0417' to parameter: 1
2010-01-09 23:06 [DEBUG] binding '~~~~~~~' to parameter: 2
2010-01-09 23:06 [DEBUG] about to open ResultSet (open ResultSets: 0, globally: 0)
2010-01-09 23:06 [DEBUG] processing result set
2010-01-09 23:06 [DEBUG] result set row: 0
2010-01-09 23:06 [DEBUG] returning null as column: userSeq2_0_
      -> primary key 가 null인게 있을리 없다..

2010-01-09 23:06 [DEBUG] result row: null
2010-01-09 23:06 [DEBUG] done processing result set (1 rows)
2010-01-09 23:06 [DEBUG] about to close ResultSet (open ResultSets: 1, globally: 1)
2010-01-09 23:06 [DEBUG] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
2010-01-09 23:06 [DEBUG] closing statement



@Column을 명시하지 않았기에 하이버네이트가 매핑된 이름 그대로 컬럼을 찾는다.
DB의 컬럼명은 USER_SEQ인데.. 만약 DB 컬럼명이 USERSEQ였다면 제네릭이 되었을테지만..

아래처럼 고쳐주었다..

 @Id
 @GeneratedValue(strategy=GenerationType.AUTO)
 @Column(name="USER_SEQ")
 public Integer getUserSeq() {
      return userSeq;
 }

제대로 돌아간 로그 기록..

2010-01-09 23:01 [DEBUG] opened session at timestamp: 12630457058
2010-01-09 23:01 [DEBUG] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
2010-01-09 23:01 [DEBUG] opening JDBC connection
2010-01-09 23:01 [DEBUG] select this_.USER_SEQ as USER1_2_0_, this_.ANSWER as ANSWER2_0_, this_.BIRTH_DAY as BIRTH3_2_0_, this_.CREATE_DATE as CREATE4_2_0_, this_.DISABLE as DISABLE2_0_, this_.DOMAIN as DOMAIN2_0_, this_.E_MAIL as E7_2_0_, this_.EMAIL_DENY as EMAIL8_2_0_, this_.masterCodes as masterCo9_2_0_, this_.QUESTION as QUESTION2_0_, this_.RELATION_GROUP_SEQ as RELATION11_2_0_, this_.RELATION_SEQ as RELATION12_2_0_, this_.UPDATE_DATE as UPDATE13_2_0_, this_.USER_ID as USER14_2_0_, this_.USER_NAME as USER15_2_0_, this_.USER_NICK as USER16_2_0_, this_.USER_PW as USER17_2_0_, this_.USER_STATUS as USER18_2_0_ from MEMBER this_ where this_.USER_ID=? and this_.USER_PW=?
2010-01-09 23:01 [DEBUG] preparing statement
2010-01-09 23:01 [DEBUG] binding 'agnes0417' to parameter: 1
2010-01-09 23:01 [DEBUG] binding '~~~~~' to parameter: 2
2010-01-09 23:01 [DEBUG] about to open ResultSet (open ResultSets: 0, globally: 0)
2010-01-09 23:01 [DEBUG] processing result set
2010-01-09 23:01 [DEBUG] result set row: 0
2010-01-09 23:01 [DEBUG] returning '2' as column: USER1_2_0_
2010-01-09 23:01 [DEBUG] result row: EntityKey[com.jaeyeollee.model.join.Member#2]
2010-01-09 23:01 [DEBUG] Initializing object from ResultSet: [com.jaeyeollee.model.join.Member#2]
2010-01-09 23:01 [DEBUG] Hydrating entity: [com.jaeyeollee.model.join.Member#2]

2010-01-09 23:01 [DEBUG] returning null as column: DISABLE2_0_
2010-01-09 23:01 [DEBUG] returning '@naver.com' as column: DOMAIN2_0_
2010-01-09 23:01 [DEBUG] returning 'leepcs' as column: E7_2_0_
2010-01-09 23:01 [DEBUG] returning null as column: EMAIL8_2_0_
2010-01-09 23:01 [DEBUG] returning null as column: masterCo9_2_0_
2010-01-09 23:01 [DEBUG] returning '어머니 성함' as column: QUESTION2_0_
2010-01-09 23:01 [DEBUG] returning 'CG0000' as column: RELATION11_2_0_
2010-01-09 23:01 [DEBUG] returning 'CS0000' as column: RELATION12_2_0_
2010-01-09 23:01 [DEBUG] returning null as column: UPDATE13_2_0_
2010-01-09 23:01 [DEBUG] returning 'agnes0417' as column: USER14_2_0_
2010-01-09 23:01 [DEBUG] returning 'Hibernate' as column: USER16_2_0_
2010-01-09 23:01 [DEBUG] returning null as column: USER18_2_0_
2010-01-09 23:01 [DEBUG] done processing result set (1 rows)
2010-01-09 23:01 [DEBUG] about to close ResultSet (open ResultSets: 1, globally: 1)
2010-01-09 23:01 [DEBUG] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)

2010-01-09 23:01 [DEBUG] closing statement





그러니.. 제네릭이 된다.. 하하하;;;

아.. 볍신 인증했네...

난 Collection을 사용할때 항상 Generic 타입으로 객체를 생성하려한다.
이유야 generic을 사용하면 좀 간편해지니 (캐스팅을 할 필요도 없고..)

이유야 어쨋든 하이버 네이트에서도 제네릭을 붙여보았는데 ..


  1. Session session = getHibernateTemplate().getSessionFactory().openSession();
  2.  
  3. Criteria crit = session.createCriteria(Member.class);
  4. crit.add(Expression.eq("userId", member.getUserId()));
  5. crit.add(Expression.eq("userPw", member.getUserPw()));
  6.  
  7. List<Member> list = crit.list();

난 이게 될 줄 알았다. 정말 진짜...
심심풀이 만들어보고 있는데 이상하게 유저가 존재하는데도 session을 생성하려고하면 null을 뱉어내니 환장하는 수 밖에..

별 수단 다 써보다가 설마 싶어서 <Member>를 지우고 찍어보니.. 객체 주소가 찍히네...

그래서 도달한 결론은 7번 라인처럼 generic을 이용하여도 -
crit.list()를 하게 되면 return 되는 값들은 Object 형이므로 무조건 class Casting을 하여야 한다.

Membe rmember = (Member) list.get(0);

이렇게...  하면 틀린거고;;

http://yeory.tistory.com/46 여기를 참고하세요..

이글은 무식 인증 글임 ㅋ

+ Recent posts