* 사내 강의용으로 사용한 자료를 Blog에 공유합니다. Spring을 이용한 Web 개발에 대한 전반적인 내용에 대해서 다루고 있습니다.
Hibernate에서 사용된 ORM 객체들은 Entity object라고 불리웁니다. 그렇지만, myBatis의 객체는 VO, DTO라고 불리웁니다.
이에 대한 정의는 다음과 같습니다.
Entity Object
프로세스 상에 존재하는 데이터 개체로 물리적이거나 추상적인 것을 모두 포함합니다. 실제 DB의 코드에서 동작이 가능한 객체입니다. 지금 저희가 만든 예제에서는 Book, User, UserHistory 등이 각 객체로서 동작할 수 있습니다. 객체는 method를 가질 수 있으며, 생명 주기 및 객체간의 관계를 갖습니다.
VO(Value Object), DTO(Data Transfer Object)
단순히 값을 저장하는 객체입니다. Layer에서 Layer로 값을 전달할 때 주로 사용이 되며, 값에 대한 재 사용이 이루어지지 못합니다. 실제 Object에 대한 Model을 표현하기보다는 데이터를 저장하고, 전달하는데에 초점이 맞춰져 있습니다. VO, DTO를 사용하기 보다는 Map을 이용한 Dictionary 구조의 객체를 사용해도 동일한 결과를 가지고 올 수 있습니다. Entity Object를 화면에 보이기 위해서 또는 DB의 특정 query 결과를 다른 Layer에서 사용하기 위해 주로 사용됩니다.
차이를 아시겠나요? 단순히 Hibernate에서는 DB에 대한 값의 전달 뿐 아니라, 객체의 주기와 객체와 객체간의 관계까지 가지고 있는 Instance되어 있는 객체로서 움직입니다. 그렇지만, VO에서는 단순한 query값에 대한 return값을 의미하게 됩니다. 이 부분의 차이는 매우 큽니다. VO로 주로 작업을 하게 되면 결국은 절차 지향적 프로그래밍으로 동작하게 됩니다. Flow가 흐르듯이 method1 call, method2 call 식으로요. 그렇지만, 객체를 이용하게 되는 경우, 객체간의 상호 동작에 의하여 프로그램이 개발이 되게 됩니다. 이 두 객체의 사용 문제는 국내에서만 뜨거운 감자입니다. 외국은 이미 Entity가 평정을 한 상태이지만, 국내는 무척 말이 많군요. 전에 Daum에서 조사한 결과로는 해외는 8:2, 국내는 2:8 수준이라고 했습니다. 이 부분에 대한 논쟁을 따로 정리해봤습니다. 코드를 한줄 더 짜는 것보다, 이 부분에 대한 내용을 한번 정리해보는 것은 개발자들에게 있어서 굉장히 중요한 시간입니다. 다들 읽어보시고, 같이 이야기해보는 시간을 갖도록 하겠습니다.
IBatis와 Hibernate 기술적 트렌드에 대한 작은 생각입니다.
제가 알고 있기에는 세계적으로는 HIbernate가 대세이고
한국은 IBatis가 대세 정도로 알고 있습니다.
물론 제 개인적인 생각일수도 있을것 같습니다.
제 생각에는 Hibernate 프레임웍의 특성을 보면 비교적 잘 설계되고 복잡도가 상대적으로 높은편인것 같고,
반면에 IBatis는 기능은 간단하지만 SQL을 직접쓰기가 편리하고,
많은 학습없이 쉽게 사용할 수 있는것 같습니다.
그래서 전 여러분은 이 두가지 프레임웍크에 대한 생각을 듣고 싶습니다.
여러분이 이 두가지 프레임웍을 선택 하실 기회가 되거나 선택하셔야 한다면 어떤것을 왜 선택하시겠습니까?
단연 Hibernate 아닐까요?
iBatis는 2년 정도 사용했습니다만 효용성으로 따져서는 Hibernate가 압도적인거 같습니다.
진짜 개발자의 칼퇴근을 도와주는 도구는 Hibernate라고 생각되네요.
Hibernate가 초기 학습비용이 크지만 개발자 전원이 모두 알아야 할 필요는 없다고 생각됩니다.
몆몆 사람들이 Db설계와 매핑을 해준다면 나머지 분들이 도메인 설계를 하면 됩니다.
문제는 Hibernate 매핑을 다루는 사람이 고객의 신뢰와, DBA급의 권한과, Hibernate를 이해하며, 클래스설계에도 익숙해야 할듯 한데
한국에서는 그게 쉽지 않을듯 하네요.
현재 스프링으로 프로젝트를 진행중인데 Spring 2.5.6 + iBatis 조합으로 개발하고 있습니다.
초기에 Hibernate도 고려해봤는데 아직 사용법에 익숙하지 않고 여러개의 테이블을 조인해야 되는 상황에다
또 다양한 통계쿼리를 직접 작성해야 될 경우가 많아서 iBatis를 선택했습니다.
iBatis만 선택해도 어느정도의 장점을 누릴수 있지만 진정한 OR Mapping의 장점을 얻으려면 Hibernate가 해답일 거라는 생각이 드네요.
물론 DB설계가 깔금해야 되고 관련 framework에 대한 지식이 있다라는 전제가 깔려야 겠지요.
OR Mapping과 Sql mapping은 완전 개념이 틀린 것 같습니다.
약간 지나친 생각일 수도 있겠으나 전 iBatis를 쓸 꺼면 그냥 Spring JDBC를 쓰는 게 나을 꺼라 생각합니다.
CoC 스타일로 RowMapper와 SqlParameterSource를 쓰면 웬만한 SQL 매핑 문제는 해결할 수 있고, 동적 쿼리 작성 부분만 잘 잡아놓으면 iBatis가 제공하는 거의 대부분을 Spring JDBC로 커버할 수 있을 것 같습니다.
iBatis는 쿼리를 xml 파일로 따로 빼놓아서 일종의 추상화를 시키려고 하는 데 이 부분은 쓸데없는 오버헤드가 되기 쉽지 않나 생각합니다.
이 내용에 대한 이야기는 참 자주 나오네요. KSUG 에서 논의한 것만 해도 벌써 여러번 인 듯 합니다.
근데 한가지 궁금한게, Hibernate 를 SI 프로젝트에서도 사용하나요?
회사 내부 프로젝트나 자체 솔루션 개발 같은 경우 개발 조직이 공부해서 Hibernate 를 사용하면 되겠지만,
(Hibernate 에 대한 교육 비용이 존재하는 것은 모두 공감하고 계시다고 생각합니다.)
SI 프로젝트에 투입된 외주 개발자들에게 비용과 시간까지 들여가며 Hibernate 를 교육시키긴 어렵지 않나 생각합니다.
또한 iBatis 같은 경우 XML 이 따로 떨어져 있으므로 엉성한 query 를 잡아내기가 약간은 더 수월한데
Hibernate 의 경우 소스를 일일이 까 봐야 알 수 있을 것으로 생각하고, 또한 까봐도 잘 알아보기가 힘들것 같아요.
제 경우 6개월 정도 되는 프로젝트 표준을 잡을 때 Hibernate 는 위의 이유 등으로 아얘 처음부터 제외를 하고 시작했습니다.
개발자 구할 때 "Hibernate 가능자" 를 조건에 내걸었다면야 가능하겠지만, SI 프로젝트가 많은 우리나라 상황에서는
Hibernate 가 확산되기 어렵다고 생각합니다. 혹시 SI 프로젝트에서 Hibernate 를 적용해 보셨나요? 그런 경험이 있으셨다면 경험담을 듣고 싶네요.
상황에 따라 다르겠지만, 개발 업체가 기술셋 결정하는 사람과 다른 회사에서 오고
유지보수 담당자와 다른 경우라면, 더군다나 누가 들어올지 모르는 프로젝트라면 Hibernate 적용은 엄두도 못낼 일이죠.
개발자 입장에서 그다지 필요성을 느끼지 못하는 EA니 TRM 등을 논하는 이유나 '변화관리' 등의 이슈가 무관하지 않은 내용인데...
그런 이야기를 꺼내지 않더라도 종종 책임감 없는 인사가 개인적인 선호(?)로 기술만 선정해놓고 제대로 가이드도 하지 못해 프로젝트에 고통을 심어놓고, 시스템엔 버그를 심어놓고 나가는 경우가 있습니다.
이런 얘기가 나오면 항상 질문하시고 싶은 두가지가 있습니다.
- 하이버네이트는 정말 학습비용이 높나요?
- 하이버네이트를 안쓰는 이유가 여러 테이블 조인이나, 리포트(통계)쿼리가 있기 때문이라는 것이 과연 타당한 이유인가요?
저는 둘 다 아니라고 봅니다.
일반 DBA와 같은 역할을 해주는 하이버네이트의 매핑 담당자가 있다면 개별 개발자들은 별로 학습할 게 없습니다. 하이버네이트 매핑이 만들어져 있다면 90%이상의 쿼리들은 자바도 알고 SQL도 아는 개발자라면 1-2일 교육이면 충분히 다 작성합니다. HQL이 SQL에 비해서 뭐가 어렵나요? 게다가 하이버네이트의 튜닝은 개발 후 별도로 해도 그만이니까 오히려 초보자들이 덜 부담을 가지고 개발도 가능합니다. 어짜피 초대형 DB의 초고성능 쿼리가 필요한 상황이라면 SQL도 DBA가 미리 작성을 해주고 그것을 가져다 사용하는 식일테니까, 하이버네이트도 HQL이랑 최적화된 매핑 만들어서 개발자들에게 제공하면 됩니다.
나머지 10%의 리포트 쿼리나 DB의 특수한 기능을 사용하는 쿼리도, 그냥 하이버네이트의 Native SQL 쿼리매핑을 사용해서 SQL 그대로 쓰면 됩니다. 하이버네이트 안에서 일반 SQL을 사용할 수 있게 된 것은 언제부터인지 기억도 안날만큼 오래전부터 지원됐습니다. iBatis만큼 편리하게 Native SQL/XML-Entity(또는 DTO) 매핑도 해줍니다. 당연히 Stored Procedure도 호출해서 사용할 수 있습니다.
> - 하이버네이트는 정말 학습비용이 높나요?
제 생각에 하이버네이트의 전체 학습 비용이 ibatis를 배우는 다 비용보다 크다고 생각하지는 않습니다.
다만 사람들이 ibatis를 다 알고 쓰지 않는 다는 거...
아마 대부분 SI 개발자들은 ibatis의 dynamic sql이나 cache 기능도 모를 거에요.
결과를 객체에 담지도 않을 거고요.
결국 이미 알고 있는 SQL 지식을 활용해서 뭔가 앞선 기술(처럼 보이는) 뭔가를 쓴다는 이미지를 노리는 것 아닐지...
사실 생짜 JDBC 작업을 하는 것 보다는 ibatis가 편하니까요. 다만 우리에게는 spring jdbc가 있지요. ㅎㅎ
> - 하이버네이트를 안쓰는 이유가 여러 테이블 조인이나, 리포트(통계)쿼리가 있기 때문이라는 것이 과연 타당한 이유인가요?
하이버네이트 안 쓰는 이유로 이런 이유는 별로 들어보지 못했습니다.
> HQL이 SQL에 비해서 뭐가 어렵나요?
사실 별로 어렵지 않지요. 다만 이미 개발자들이 SQL은 친숙한데 HQL은 새로 배워야 한다는 것이 문제지요. SI는 프로젝트
는 파견 개발자가 대부분인데 이 친구들이 참 대책없는 경우가 많습니다. struts나 spring의 아주 기본 내용만 교육해도
그 걸 이해 못해서 버벅이는 일이 많지요.
hibernate가 native sql로 쿼리할 수 있는 기능도 가지고 있지만 그거 설명하면 10명 중 한두명 이해하면 다행일것 같아요.
사실 전 ibatis가 세상에 없었다면 참 좋았겠다는 생각입니다. 꼭 hibernate를 써야만 하는 건 아니지만 분명히 jdbc를 직접 쓰는 것 보다 hibernate 같은 orm을 쓰면 비용이 훨씬 줄어드는 임계점이 있는데 ibatis가 그 임계점을 훨씬 뒤로 밀어버린 것 같아요. 기존에 습득한 기술을 우려 먹을 수 있는 기간이 늘어나는 거죠.
제가 hibernate를 쓰지 않는 상황이 아쉬운 건 단순히 hibernate라는 좋은 기술을 쓰지 못하기 때문이 아니라 ORM의 보급이 늦어짐과 동시에 객체지향 기술도 보급이 되지 못하는 것 아닌지 생각이 들어서 입니다.
> - 하이버네이트는 정말 학습비용이 높나요?
제 생각에 하이버네이트의 전체 학습 비용이 ibatis를 배우는 다 비용보다 크다고 생각하지는 않습니다.
ibatis랑 비교해서가 아니라 하이버네이트라는 기술자체가 높은 초기 학습비용을 가진 것인가 하는 질문이었습니다. ResultSet을 뷰단까지 직접 끌고 가서 사용하던 10+년전 방식이 아니라면 대부분 DTO에 결과를 담아서 주고 받는 DAO 패턴에 익숙할 것입니다. iBatis도 마찬가지지요. 요즘은 맵을 선호하기도 한다지만 그렇다고 객체에 담는 걸 모를까요? (설마...) 정보를 의미있는 자바 객체에 담아서 전달하고 매핑하는 것은 이미 익숙한 작업입니다. 그런면에서 하이버네이트와 같은 ORM이 그다지 특별한 이해력을 요구한다고 보지 않습니다.
다만 사람들이 ibatis를 다 알고 쓰지 않는 다는 거...
아마 대부분 SI 개발자들은 ibatis의 dynamic sql이나 cache 기능도 모를 거에요.
결과를 객체에 담지도 않을 거고요.
저는 ibatis의 고급기능이 하이버네이트보다 어렵더라고요. 하이버네이트 2시절에도 xdoclet, 3에선 annotation을 이용해서 매핑정보를 넣다보니, XML로 만든 매핑정보는 보기만 해도 머리에 쥐가 나더군요.
> HQL이 SQL에 비해서 뭐가 어렵나요?
는 파견 개발자가 대부분인데 이 친구들이 참 대책없는 경우가 많습니다. struts나 spring의 아주 기본 내용만 교육해도
그 걸 이해 못해서 버벅이는 일이 많지요.
대책없는 개발자들은 SQL가지고도 동작은 하지만 성능문제를 일으키는 각종 악성 쿼리를 만들어 냅니다. 대책없는 개발자는 뭘 해도 대책없습니다.
hibernate가 native sql로 쿼리할 수 있는 기능도 가지고 있지만 그거 설명하면 10명 중 한두명 이해하면 다행일것 같아요.
하이버네이트의 Query 오브젝트를 사용할 줄 안다면 native SQLQuiery를 사용하는 방법은 쉽게 마스터 할 수 있다고 봅니다. Native SQL을 오브젝트 매핑 안하고 scalar(List of array)로 가져올거라면 아래와 같이 한줄이면 충분합니다. 이미 존재하는 Entity에 매핑하는 것은 메소드 하나 더 붙이면 되고, 리포트 쿼리라 임의의 DTO로 매핑하는 것도 두 줄이면 충분합니다. 저는 예제 보여주고 10분 설명하면 10명 모두 "간단하네" 하더군요.
sess.createSQLQuery("SELECT * FROM CATS").list();
사실 전 ibatis가 세상에 없었다면 참 좋았겠다는 생각입니다. 꼭 hibernate를 써야만 하는 건 아니지만 분명히
jdbc를 직접 쓰는 것 보다 hibernate 같은 orm을 쓰면 비용이 훨씬 줄어드는 임계점이 있는데 ibatis가 그 임계
점을 훨씬 뒤로 밀어버린 것 같아요. 기존에 습득한 기술을 우려 먹을 수 있는 기간이 늘어나는 거죠.
제가 hibernate를 쓰지 않는 상황이 아쉬운 건 단순히 hibernate라는 좋은 기술을 쓰지 못하기 때문이 아니라 ORM
의 보급이 늦어짐과 동시에 객체지향 기술도 보급이 되지 못하는 것 아닌지 생각이 들어서 입니다.
저는 ibatis 쓰지 말고 하이버네이트 쓰자는 얘기는 별로 하고 싶지 않습니다. 개발만 잘 한다면 뭐 기술이야 입맛대로 또는 영업&정치적인 이유에 따라서 쓰면 되는 것이고요.
다만 하이버네이트를 사용하지 않는 이유를 하이버네이트 자체에 심각한 문제가 있기 때문인 듯이 둘러대는 것은 맘에 안듭니다.
전 솔직히 Hibernate는 어렵습니다.
특히나 쿼리를 생성하기 위한 'Criteria' 사용법이 너무 어렵습니다. 일반적인 조인관계는 그렇다쳐도
사용하기 위해선 맵핑 설정을 충분히 고려해서 사용해야하고 차근차근 개발하기에는 무리가 있더군요.
iBatis는..초기에 조금 사용해봐서 고급기능까지는 안해봤지만, 어렵게 접근은 안해도 되더군요.
그래서 앞으로는 좀더 Hibernate를 공부하면서 Spring JDBC를 사용해보려 합니다. ㅎㅎ
> 좀더 진실해지자면,
Hibernate를 어렵게 느끼는것은 객체지향 프로그래밍에 익숙하지 않아서가 아닐까요?
iBatis가 쉽게 느껴지는건 내가 좀더 절차지향을 편하게 느껴지는 습관 때문일거라는 생각 입니다.
그러면 사실 나는 OOP가 가능한 JAVA를 사용하면서 절차지향적인 면을 더 편하게 느끼고 있는 것입니다.
앨런 홀럽의 말처럼, JAVA를 절차지향적으로 작성하면 JAVA를 사용할 이유가 없습니다.
차라리 절차지향 언어로 작성하는것이 더 효율적일지도 모릅니다.
왜 iBatis 가 절차지향적이고 Hibernate 가 객체지향적이라고 생각하시는지 궁금해요.
sql 들어가면서 나름 OOP 개념으로 의욕적으로 설계를 하다가 깨지는 경향 (껍데기뿐인 모델 등등) 이 있다, 그리고 Hibernate 와 같은 ORM 도구를 "잘" 활용할 경우 OOP 적으로 좀 더 탄탄한 설계를 할 수 있다고 하는 글은 본 것 같은데 절차지향과 연관하여 이야기 하신 것은 잘 모르겠어요. 앞부분을 이해를 하지 못하여, 뒷 단락에 하신 말씀도 이해가 되지 않습니다. 절차지향보다는 OO - relation DB 컨셉의 짬뽕이 문제가 아닐까 해요.
다시 되돌아와서 ORM 도구를 잘 활용하면 더 OOP적으로 좋은 설계를 이끌어 낸다는 점에는 동의합니다.
밑에 강명성님 글을 보고 생각난 것인데 Join 때문에 Hibernate를 못 쓰겠다는 말이 나오는 이유가 성한님 말씀 처럼 객체지향에 익숙하지 않은 것과 관계 있다고 생각이 듭니다.
이건 사실 제가 iBatis를 사용해서 쿼리 결과를 객체에 담는 방법을 개발자들에게 설명하면서 받은 질문 때문에 알게 된 건데요.
RDBMS에서는 DB의 table 평면 공간에 배치되어 있고 서로 동등한 수준에서 관계를 맺는 구조이고 객체 지향에서는 여러 클
래스들이 상속이나 구성을 통해서 관계를 맺는 구조인데 이 두 구조 간의 차이가 생각보다 큰 것 같습니다.
간단히 말해서 RDBMS에서 SQL을 사용하면 이런 저런 테이블을 어떻게 복잡하게 조인해서든 원하는 컬럼 한 두개를 평면적으로
읽어 올 수 있는데 객체를 사용하면 입체적인 구조로 담아와야 한다는 거죠. 뭔가 미리 계획을 잘 세워야 하고 거추장스럽다는 인상을 갖는 듯 했습니다.
단순히 join때문이 아니라 HQL을 토드나 오렌지에서 테스트해 볼 수 없어서 싫어하시는게 아닐까요?
전 프로젝트에서 개발자분들은 HQL보다는 flush같은걸 잘 모르셔서 문제가 생기더군요
따지자면 생명 주기도 있고 lazy loading도 있고 여러가지 걸림돌(?)들이 있지요.
위에서 토비님이 질문하신 것 중 두번째에서 제가 join은 별 문제 없는 것 같다고 말을 하고 보니 이런 생각이 나더라고요. 그
래서 말씀드려 봤습니다. ^^
HQL이야 LOG에 찍히는 sql 구분 사용해서 토드(이 비싼 놈)에서 돌려보면 되기는 하지만 일단 ORMap 담당자가 이런 일
을 해주면 개발자들은 신경 안 써도 되겠죠.
ORMap 담당자는 필수 같아요. ^^
토드처럼 모델(엔티티) 구조를 보면서 HQL을 이클립스 등에서 직접 만들고, 실행 해볼 수 있는 하이버네이트 툴도 꽤 오래전부터 사용되고 있습니다.
Hibernate 사용에 있어 테이블 조인 결과를 어떻게 object에 매핑하느냐와 같은 사용법 문제는 큰 이슈가 아니라고 봅니다. 오히려 많은 SI 프로젝트를 보면, 새로운 시스템 도입 과정에서 업무 분석도 불충분한데 온갖 방법론이나 기술 도입을 통해 결과적으로 만든 시스템에 대해 누구도 만족하지 못하는 경우를 경험합니다. '최종 사용자'는 물론이고 '유지보수 담당자'도 일관성을 찾기 힘든 시스템을 마지못해 인수받는 모습을 어렵지 않게 찾아볼 수 있습니다. 공교롭게 규모가 커서 예산이 충분할수록 이런 현상은 더 심해지는 듯도 보입니다.
정보 시스템 개발을 할 경우 시스템 핵심정보라 할 수 있는 "모델"은 주로 ERD에 녹아듭니다. 현장에서 객체 모델 필요성(?)을 주장한지 5년째이던 2007년 즈음에 현실을 인정했습니다. 넓은 강당에서 고객과 ER 모델러가 커다란 ERD를 펴놓고 격론을 벌이는 모습을 보고서 단념했죠. 과연 객체 모델을 가지고 키맨 사이에 논쟁을 벌이는 날이 언제 올까요? 일회성으로 진행하는 프로젝트에선 요원할 일일 지도 모릅니다.
성철님이 말씀하신 바대로 능력(?)을 전혀 가늠할 수 없는 외주 개발자가 무척 많습니다. 거기에 연차까지 많으면 설득에도 오랜 시간과 노력이 필요합니다. 그런 분을 이끌고 촉박한 시간 안에 프로젝트를 하는데 Hibernate를 쓰자고 하는 일은 헛심쓰기에 가까운 경우가 많습니다. 특히, 업무 설계가 엉성한 경우는 Sub-query와 UNION 없이는 화면 하나도 구현이 불가한데, 이런 경우 굳이 Hibernate를 도입이 주는 이점이 별로 없습니다.
RDB의 join만큼 기껏 설계한 ERD의 가치를 떨어뜨리는 것도 없다고 봅니다.
1:n을 join해서 한방에 가져오면 catersian product에 theta-join이 일어나 1:n의 릴레이션의 의미는 사라진 전혀 새로운 포맷을 가진 직관적이지 않은 결과가 돌아옵니다. 과연 그게 이해하기 쉬운 것인가요? 차라리 ERD에 나타난 엔티티 릴레이션의 구조대로 1:n의 관계를 유지해서 가져오는 하이버네이트와 같은 ORM이 ERD의 개념을 더 충실하게 나타내고 있다고 봅니다.
서브쿼리건 UNION이건 어짜피 SQL을 쓰나 Hibernate를 쓰나 쿼리작성 복잡도는 비슷합니다. 차라리 join의 갯수가 증가하면 HQL이 SQL보다 훨씬 이해하기도 편하고, 역시 ERD에도 잘 부합됩니다.
구지 ORM의 특징이라고 하는 상속개념도 ERD에서 다 나타납니다. 그걸 물리적인 스키마로 표현하면 명시적으로 드러나지 않을 뿐이지, 원래 ERD에 있던 개념이 사라지는 것은 아닙니다. 하이버네이트가 ORM으로 성공한 이유는 백그라운드의 RDB를 무시하지 않고, 그 특징을 적극 활용하면서 프로그래밍 인터페이스 적인 측면을 강조했기 때문이지, 무슨 RDB의 ERD설계와 개념을 제치고 다른 걸 들고 나와서가 아닙니다. 하이버네이트를 마치 ODB처럼 생각하는 것은 완전 잘못된 이해입니다. 하이버네이트는 RDB에 최적화된 또다른 접근방법의 하나일 뿐입니다. 테이블과 인덱스로 구성된 RDB에 SQL이라는 추상적인 인터페이스를 도입한 것과 다를바 없다고 봅니다.
이미 익숙한 기술을 고집해서 새롭고 보다 나은 기술에 저항했던 것은 ISAM에서 RDB로 넘어올 때도 마찬가지였고, 4GL을 도입할 때도, 자바가 메인스트림에 등장했을 때도, 웹 프로그램이 주류가 되려고 할 때도 마찬가지였습니다. 가치를 아는 사람들이 늘어가고 언젠가 임계점을 넘으면 ORM이나 post-RDB 기술이 SQL을 밀어내고 주류가 될겁니다. 아마 그때까지는 "ERD가 기업에는 중요하니 하이버네이트는 안된다"는 FUD가 계속 나타나겠지만요. 차라리 우리는 제대로된 ERD도 없고, 그때마다 주먹구구식으로 만들어서 테이블이 엉망진창이라 매핑할 엄두도 못내겠다라고 하면 차라리 이해가 갈텐데 말이죠.
온라인 상에 Hibernate에 대한 FUD를 퍼뜨리는 사람이 있을 순 있겠지만, 실제 현장에서 FUD 탓에 Hibernate 도입을 꺼리지는 않는다 생각합니다.
본질은 SI 프로젝트에서 주로 형식적인 부분과 절차적인 면은 중요시하지만, 내용에 해당하는 설계 자체에 대해서는 심각하게 다뤄지지 않는다는 점이죠. 외주 개발을 하는 SI 특성상 시스템을 사용하는 고객사 환경을 감안하지 않을 수 있습니다. 이를 위해 EA니 ITA 등을 논합니다. 수 년전부터 금융, 공공 등을 필수로 수행을 했죠. EA 안에서도 DA와 AA는 두드러진 연계점을 찾아보기 힘들더군요.
ERD는 데이터에 대한 정적인 뷰이기 때문에 실제 최종 사용자가 애플리케이션을 사용하는 시점에서 어떻게 데이터를 쓰는지. 가령, 어떻게 묶여서(가령 객체 형태로) 쓰이는지,수정이나 노출(조회) 빈도는 어떤지 등등 동적인 측면에 대해서도 충분히 고민을 해야 합니다. 만일, 이런 내용을 협의하고 고민하고, 그에 따라 시스템 속성을 변경할 필요가 있다면... 객체모델(UML로 그렸든.. 사람들 머리속에 있든)은 강력한 도구가 될 것입니다. 이런 곳에서라면 Hibernate는 정말 좋은 솔루션이라고 생각합니다. 그리고, 추후 그럴 가능성이 있는 곳이라면 학습 비용이나 변화에 대한 저항이 존재하더라도 충분히 대가를 치를 가치가 있겠죠.
하이버네이트 적용 성공에 대한 관건은 RDB의 DBA와 같은 역할을 하는 ORMA가 있어야 한다고 생각됩니다.
그래서 개발자 개개인의 기술에 대한 학습부담을 줄여주어야 합니다. 필요에 따라 HQL이나 페칭 전략 등에 대한 검증과 조언을 해주고, 개발자들의 코드에 나온 Raw SQL을 분석해서 모델레벨의 튜닝을 최적화 해주는 독립적인 작업을 지속적으로 수행해줘야 하죠.
하이버네이트의 장점은 모델레벨에서 페칭, JOIN 방식이나 캐슁 등에 영향을 주는 설정을 개발된 코드나 HQL에 영향을 주지 않고도 조절이 가능하다는 점입니다. 그런면에서 SQL보다 개발자들 수준에 영향을 덜 받을 수 있는 장점이 있습니다만, 그만큼 숙련된 하이버네이트+RDB를 모두 잘아는 뛰어난 전문가가 한명씩은 필요하다는 부담이 될 수도 있습니다.
물론 페칭 방식, 세컨레벨 엔티티 캐쉬에 따라서 HQL에서 한번에 가져올 것이냐, 일부를 가져온 뒤에 캐쉬에서 lazy loading을 하게 할 것이냐의 결정은 코딩 구조에 영향을 주기도 합니다. 그런 결정은 대부분 초반에 어느정도 내려져야 할것입니다. 가장 손쉬운 것은 리드온리성 레퍼런스 정보는 캐슁을 한다는 정도면 되겠죠. 쿼리 캐슁은 나중에도 얼마든지 조정이 가능하니까 뭐 상관없습니다만. 그런 정도 팁들은 JPWH 책 한권만 봐도 아주 자세하게 잘 나와있습니다.
HQL은 복잡한 쿼리 위주라면 named query로 해서 XML로 뺀 후 ORMA/DBA가 관리하게 하는 것도 좋은 방법입니다. "데이터가 회사의 가장 중요한 자산이다"라고 생각하는 기업이라면 SQL에는 개발자가 손도 못대게 하고, DBA들이 미리 만들어서 제공하는 경우가 많을 겁니다. HQL도 마찬가지의 접근을 할 수 있죠.
SI현실을 가지고 얘기하면 사실 끝이 없습니다. 엉망인 것도 워낙 제각각이라서 말이죠. 친한 DB컨설턴트의 말을 들어보면 ERD보고 SQL도 제대로 못만드는 개발자들도 여전히 많이 있다고 합니다.
SI현실을 까놓고 보자면 스프링을 왜썼나 모르겠다 싶은 프로젝도 많이 보입니다. 개발자 수준은 안되고, 학습부담은 크고, 유지보수에 대한 대책이나 후속조치도 불분명하고, 현 상황에서 썼을 때 그다지 장점도 없어보이는 대표적인게 스프링이라고 생각됩니다. 친숙한 JSP Model1이나 개발자들이 제법 익숙한 스트럿츠1+헬퍼 클래스 또는 벤더 지원과 툴도 빵빵한 EJB를 쓰면 되는데 굳이 장점이 좀 있다고 SI현실에 부합하지 않는 어려운 스프링을 도입해야 할까요?
물론 스프링을 안쓰는 곳은 FUD 때문이거나 다른 기술적인 이유가 아닌, 더 현실적인 타당한 이유가 있겠죠.
그래도 "EJB는 표준기술이니까 다들 익숙하고, 스프링은 오픈소스니까 학습비용도 크고, 서버도 톰캣에서밖에 안돌고 메인프레임 연결도 할 수 없고 어쩌고 등등" 하면 곱게 못넘어갈 것 같습니다.
또는 현실적인 문제는 극복할 의지와 가능성이 있는데, FUD 때문에 꺼리는 사람이 있다면 잘못이해하고 있는 것을 바로 잡아주는 것이랑 "SI 현실을 무시하고 스프링 써라"라고 말하는 것은 분명히 다릅니다.
저는 스프링을 쓰고 싶으나 분산트랜잭션이 필요해서 스프링을 도입못하고 있다는 사람을 만나본 적이 있습니다. 스프링에서도 훨씬 세련된 방식으로 분산트랜잭션을 사용할 수 있다고 설명해줬더니 아주 좋아하더군요. 물론 당장에는 다른 현실적인 한계로 인해서 스프링을 도입 안할 수 있습니다. 하지만 다음 번에는 좀 더 도입할 의욕을 가지고 장애물을 극복하고 도전할 용기를 그만큼 더 낼 수 있을 거라고 기대합니다.
하이버네이트에 대해서도 마찬가지 생각입니다. 현실적으로는 무리다라고 말하는 것과 기술적인 오해를 가지고 힘들겠다라고 말하는 것은 분명 다릅니다.
솔직히 한국에서 하이버네이트에 대한 제대로된 기술적인 비판이나 분석이 진행된 것을 본 기억이 없습니다. 그냥 "성능이 떨어져서..", "데이터 모델이 복잡해서..", "복잡한 조인 쿼리가 있어서..", "개발자들이 배우기 힘들어서.." 라는 식입니다. 좀 구체적인 내용을 가지고 얘기를 하면 좋겠는데 말이죠. 그러면 충분히 답변 가능한 것들이고 반박도 할 수 있고, 증거도 보일 수 있을텐데 말이죠.
그런데 하이버네이트 제법 쓰이는 것 같습니다. 상대적으로 아직 미미할지는 모르겠지만, 수십억원 급 또는 그 이하의 중소규모 프로젝트들을 중심으로 제법 쓰이고, 만족스럽게 결과를 냈다는 얘기도 종종 들리더군요. 작년에 벌써 200여군데의 현장에 적용했다고 하는 SDS의 애니프레임도 하이버네이트를 사용하지 않았나요? 하이버네이트는 스프링과 비슷하게 한번 제대로 쓰면 계속 쓰고 싶어지는 중독성이 있는 것 같습니다. 어쩌면 생각보다 빨리 주류기술로 올라설지 모르죠.
* FUD (Fear, Uncertainty, and Doubt)
이 글을 보니 위에 제가 애매하게 쓴 제 생각을 더 명확히 정리할 수 있네요.
ORM이 ERD 구조를 더 충실하게 유지한다고 하셨는데 맞습니다. 그런데 그런 특성이 ORM 도입을 힘들어하는 이유가 되는 것 같습니다.
우리나라 개발자들을 결과를 빨리 얻기 원하는 것 같습니다.
쿼리 하나 날려서 원하는 결과를 얻고 이 결과를 기계적으로 화면 단에 전달에 표시하기를 원하는 거죠. Data가 구조화된 상태
로 관리되는 것은 DB로 충분하지 굳이 메모리에까지 구조화된 상태로 가지고 오기를, 그래서 그 자료를 다시 어떤 로직으로 처리하
기를 원하지 않는 것 같습니다.
데카르트 곱이 ERD의 구조를 깨트린다고 하셨는데 데카르트 곱의 결과를 가지고 어떤 처리를 할 것이 아니라 그것 자체가 결과라
면 사실 그런 구조 파괴가 문제되지는 않으니까요.
저는 이렇게 SQL에 대부분의 주요 로직이 들어가고 Java 코드는 단순히 인자를 전달하고 결과를 반환하는 일을 주로 하는 방식의 개발 관행이 바뀌지 않는다면 ORM은 일할 양이 늘어나는 번거로운 기술로 받아들여질 듯 합니다.
결과를 빨리 얻기를 원하는 점은 개발자에 국한한 이야기는 아닌 듯 합니다.
그리고, 팀 단위 작업이라면 ERD는 아무 개발자에게나 맡기지 않잖아요.
ERD를 구성하는 어휘도 관리하고, 여력이 있는 경우 모델링과 검증을 위한 전문 인력을 두기도 하고
논리와 물리로 단계를 나누어 정규화도 하고, 이후에도 ERD에 입각해서 DB 객체를 만들어내고 관리하는 과정에 상당한 공수를 투입합니다.
즉, 중요하게 취급하죠.
하지만, ORM에 대해서도 그럴까요? ORM은 EA/ITA, SOA처럼 큰 돈을 보장하는 fancy한 기술이 아니기 때문에
지속적으로 노하우나 이점을 실제로 맛 보고, 이를 공유하고 가시화 되어지는 긴 과정이 필요한지 모릅니다.
어떤 면에서는 Spring이 주류로 올라선 과정을 ORM도 겪어야 하지 않나 싶고, 이미 그런 과정 중에 있는지도 모르죠.
하이버네이트가 결과를 빨리 얻는데는 더 낫다는 것을 알면 좋을텐데 말이죠.
lazy loading이랑 object navigation을 써서.. 대충 엔티티 하나 가져와서 뷰단에서 마구 관련 정보를 다 끌어와 붙이고 추가해도 되자나요. 매번 가져올 필드랑 조인할 테이블이 생기면 SQL을 고치고 화면도 고치고 하는 것보다 훨씬 편한데 말이죠.
애니프레임에 대해 말씀하신 부분에 오해의 소지가 있어 관련 조직에 몸담고 있는 제가 다시 부연 설명을 드리면,
일단 작년 한해동안 SDS 에서 자체적으로 수행한 프로젝트가 200 여군데가 되지는 않습니다^^; 아마도 예전의 SYSTEMiER 를 포함하여 SDS에서 수주하여 Framework 지원까지 발생한 프로젝트 수로 생각됩니다.
또한 대부분의 현장 프로젝트에는 SQL Mapper 류인 QueryService 가 사용되었고, ORM 기술로 현장 프로젝트를 진행한 사례는 많지 않은걸로 알고 있습니다. 위에서 여러분들이 말씀하신 SI 프로젝트의 대표적인 사례겠죠. 동일한 유형의 단순 CRUD App. 를 코드 제너레이션 기반으로 찍어낼 때는 확실히 ORM 이 장점이 있고 사용 사례도 있습니다만..
애니프레임에서는 Hibernate 에 대한 문서화나 일부 기능 확장 및 Sample App. 등에 레퍼런스를 제공하기도 하고, 내부적으로 진행되는 프레임워크 기능 영역에 현재 JPA 기반으로 진행중인 부분도 있습니다만, 아직까지 현장에서 ORM 을 채택하는 데는 진입장벽이 있는것 같습니다. 최근에 릴리즈된 AnyframeGen 에서는 JPA 기반의 persistence 영역을 동등한 레벨에서 지원하고 있고 계속적으로 ORM 에 대한 가이드를 강화하려고 노력은 하고 있습니다.
개인적으로 ORM 를 현장에서 사용할 때 가장 문제가 되는 부분은 relation 관계를 nested 형태의 객체로 작성하는 것 자체가 아닐까 합니다. SQL 을 직접 사용하는 경우 객체 맵핑을 한다 하더라도(그냥 Map을 쓰는 경우가 현장에서는 더 많죠) flat 한 형태로 대부분 처리하였을 것인데 이 부분의 변경은 영향이 가장 큰것 같습니다. 특히 데이터를 담고 있는 객체는 UI 를 비롯한 전체 레이어에서 사용되므로 변경 영향이 큰것 같습니다. 특히 우리나라에서 많이 사용되는 X-Internet 류의 데이터 처리 객체로 컨버전을 해야하는 경우가 상당히 많은데 이런 부분도 어려움이 존재하고요..
SQL 을 직접 사용하는 경우보다는 transaction 발생이 미뤄질 때 exception 에 대한 처리, fetching 전략, lazy loading, clustering 환경에서의 cache sync. 문제 등 고려할 것들이 더 많아지므로 저부터도 쉽게 접근하기는 어려운 것 같습니다.
점차로 우리나라에서도 ORM 이 많이 사용될 것은 의심치 않습니다. 그렇게 되려면 현장의 성공사례가 많아지고 이에 대해 제대로 리드할 줄 아는 기술자가 많아져야 하겠죠.
정말로 많은 이야기들이 나옵니다. 이러한 이야기들은 전에 서과장님과 저랑 자주 하던 이야기이기도 했고요.
만약 애플리케이션 개발자가 DB설계를 직접 할 수 있거나, 영향력을 줄 수 있는 위치에 있다면 하이버네이트가 좋고, 아니고 DBA팀을 비롯한 애플리케이션 쪽은 전혀 모르고 DB만 고려하고 설계하거나 이미 오래전에 만들어져서 운영준인 레거시DB라는 JDBC를 선택하는 것이 낫다
이유가 뭘까? 왜 같은 DB이고 같은 애플리케이션이 결국 사용할 것인데 개발자들이 직접 DB를 관장하면 하이버네이트에 적합하고, 아니라면 부적합한 것일까? 어떤 이들은 이것을 하이버네이트는 객체DB스타일의 설계가 필요하기 때문에 ODB적인 구조로 DB를 특별하게 만들어야 하기 때문에 객체설계 후 그에 따른 DB스키마 작성이 필요하기 때문이라고 말한다. 하이버네이트의 기본도 모르는 바보들의 주장이다.
"스터디 끝나고, 간단히 식사를 하면서 왜 국내에서는 하이버네이트 보다 iBatis가 더 각광 받느냐에 대한 의견 교환이 있었습니다. 비즈니스 모델링 단계에서 개발자 혹은 설계자가 자료 구조에 대한 고민을 하고 되는데, 객체지향 분석/설계에 충실하다면 객체 모델링을 통해 도출된 데이터 구조 자체를 저장소(repository)로 손쉽게 매핑(mapping)할 수 있는 하이버네이트가 유리하다는 점에서는 동의했습니다. (사실 제 첫번째 직장이 객체형 데이터베이스 회사였기 때문에 충분히 수긍할 만한 의견이었습니다.)
하지만 국내 IT 현장에서 가장 큰 발언권을 가진 사람들은 개발자가 아니라 시스템 운영자들 혹은 데이터베이스 관리자들입니다. IT를 잘 모르는 경영진 입장에서는 아무래도 회사의 자산이라고 여겨지는 것이 바로 데이터베이스이고 프로그램은 덜 중요해 보이거든요. 그러다 보니, 시스템 개발 현장에서 가장 먼저 그리고 중요하게 분석/설계되는 것은 업무 요건이 아니라 바로 데이터베이스 설계입니다. 데이터 구조가 먼저 설계되고 쿼리를 만들고 그 위에 어플리케이션을 탑재하는 순서로 개발하니 당연히 하이버네이트는 적합한 프레임워크로 고려될 수 없게 되는 것입니다."
제대로 DB설계가 된다면 왜 그것이 하이버네이트에는 적합하지 않다는 말인가? 참 답답하다. 이 글을 읽다가 답답한 마음이 들어 이 글을 쓰기 시작했다.
내가 실무 프로젝트를 초기에 경험 할때는 코볼에 ISAM에 익숙한 노땅 개발자들의 전성시대에서 RDB와 같은 신기술이 막 떠오르려고 하던 때이다. 또 틈새를 비집고 UniSQL과 같은 허접 ODB도 설쳐대던 때다. 그때 ISAM에 익숙한 선배 개발자들의 푸념이 기억난다. 메인프레임에서 ISAM으로 했으면 이 정도는 순식간에 완벽하게 착착 다 만들었을 텐데 이게 무슨 장난감 같은 유닉스에, 복잡한 언어인 C에, 배우기도 힘든 3-Tier기술에, 성능도 떨어지는 RAD툴에 RDB까지 정신이 없다고 투덜대던 시절이다. 왜 복잡하고 지저분한 SQL을 이용하는, ISAM에 비해 성능도 떨어지는 RDB를 써야 하냐는 그때 그 사람들의 모습이 바로 지금 SQL에 익숙한데 왜 하이버네이트와 같은 새로운 기술을 또 공부해야 하냐라고 저항하는 개발자들의 모습과 꼭 닮았다.