Whiteship's Note


6.5. DAO 테스트에서 연관 관계 테스팅



테스트의 시나리오는 다음과 같습니다.

멤버1 = 기선, 멤버2 = 승택님, 멤버3 = 물개 선생님
그룹1 = Agile Java Network, 그룹2 = OpenSeed

이들의 관계는 다음 그림과 같습니다.
사용자 삽입 이미지
위와 같은 멤버의 그룹정보를 세팅하고 맞게 들어갔는지 각 멤버가 소속된 그룹의 갯수를 확인하여 봅시다.

테스트 코드 보기

하늘색 부분이
        keesun.join(agileJavaNetwork, "운영 요원");
        keesun.join(openSeed, "일반 회원");
        paradozz.join(openSeed, "일반 회원");
        seal.join(openSeed, "운영자");
이런 식으로 처리가 되면 좋겠다는 생각을 해봅니다.
top

  1. Favicon of http://seal.tistory.com BlogIcon 물개선생 2007.01.19 11:23 PERM. MOD/DEL REPLY

    하늘색 처리에 대한 부분은 BL에서 하게 되겠죠?
    희망하신 내용과 유사하게 API를 설계하면
    memberGroupBl.join(Member m, Group g, GroupT, RoleType r) 이런 signature가 되지 않을까 싶은데,
    bl.join(seal, openseed, RoleType.OPERATOR); 이런 식으로 활용되겠네요..
    나중에 DDD 개념으로 도메인에 국한된 로직을 BL에서 도메인으로 옮긴다면 기선씨가 희망하는 대로 사용할 수도 있을 것 같네요. :)

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2007.01.19 14:08 신고 PERM MOD/DEL

    오호.. 그렇군요.

    그런것이 DDD라고 간략하게 선생님께서 설명해 주셨던 것이 생각나네요. :)

    BL에서 특정 도메인에 속하는 것을 도메인에게 넘겨주면 "누가 어떤 그룹에 어떤 역할로 가입을 한다." 이런 구어체 표현이 가능해 지는거군요. 훨씬 코드 보기가 좋아질 것 같아요.

  2. Favicon of https://px.tistory.com BlogIcon 김민재 2007.01.20 11:24 신고 PERM. MOD/DEL REPLY

    BL이 뭘까요?

    Favicon of http://whiteship.tistory.com/ BlogIcon 기선 2007.01.20 12:31 PERM MOD/DEL

    Business Layer 아닐까요?

    Favicon of https://px.tistory.com BlogIcon 김민재 2007.01.22 00:07 신고 PERM MOD/DEL

    나도 그렇게는 생각을 했다만.. ㅠㅜ

Write a comment.


6.4. 연관 관계 처리를 위한 메소드 구현.



Member와 Messenger의 연관 관계에서 만약에 어떤 Member 객체가 새로운 메신저 정보를 추가했다면 Member에 있는 messengers에 새로운 Messenger 객체가 추가 되어야 하고, 추가되는 Messenger 객체에 있는 member라는 멤버 변수는 자기 자신으로 세팅되어야 합니다.

즉 다음과 같은 두 줄의 코드가 필요합니다.
getMessengers().add(messenger);
messenger.setMember(this);
이 두줄의 코드는 항상 붙어있어야 하기 때문에 하나의 메소드로 묶어 둡니다.

삭제도 마찬자기로 다음의 두 줄의 코드가 묶여 있어야 합니다.
getMessengers().remove(messenger);
messenger.setMember(null);

위 코드들을 Member 클래스의 messenger의 게터 세터 아래에 구현해 둡니다.
    @OneToMany(mappedBy="member")
    public Set<KMessenger> getMessengers() {
        if(messengers == null) messengers = new HashSet<KMessenger>();
        return messengers;
    }
    public void setMessengers(Set<KMessenger> messengers) {
        this.messengers = messengers;
    }
    public void addMessenger(KMessenger messenger){
        getMessengers().add(messenger);
        messenger.setMember(this);
    }
    public void deleteMessenger(KMessenger messenger){
        getMessengers().remove(messenger);
        messenger.setMember(null);
    }

게터에 보시면 빨간 줄로 한줄의 코드가 삽입 되었는데요. 이 것은 처음으로 새로운 Messenger 정보를 추가하려고 할 때 getMessengers()를 출력하는데 이 때 Set 객체가 없기 때문에 null pointer exception이 발생하기 때문입니다.
top

Write a comment.


6.3. 연관 매핑 정보 입력하기



Member와 MemberGroup의 1대다 관계를 표시해 보겠습니다.

1. Member의 getMemberGroup 메소드 위에 @OneToMany 어노테이션을 사용해서 Member입장에서 이 관계가 1대다 임을 표시합니다.

이때 @OneToMane의 속성중에 mappedBy의 값에 상대방 객체에서 자기 자신의 객체를 참조하는 멤버 변수 이름을 적어 줍니다.
MemberGroup에서는 Member객체를 member라는 변수로 참조 하고 있기 때문에 다음과 같이 적어 줍니다.

    @OneToMany(mappedBy="member")
    public Set<MemberGroup> getMemberGroups() {
        return memberGroups;
    }

2. MemberGroup의 getMember 메소드 위에는 @ManyToOne 을 사용해서 MemberGroup 입장에서는 이 관계가 다대1 임을 표시합니다.

이 때 Owner Side를 1대다 관계에서 '다'쪽에 해당하는 MemberGroup으로 정하기위해서 @JoinColumn을 추가하고 속성중에 name 속성을 참조하는 객체가 가지고 있는 주키에 해당하는 멤버변수의 이름(Join관계에서 자신의 FK에 해당하는 상대방의 PK)을 적어 줍니다.

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="memberId")
    public Member getMember() {
        return member;
    }

3. 클래스를 로딩할 시점에 이 객체와 연관된 다른 객체들을 미리 읽어 들이겠냐는 설정을 합니다.

위에 보이는 FetchType.LAZY 로 설정하면 getMember 메소드가 호출 될 시점에 연관된 객체들을 불러 오게 됩니다. 이와 반대로 연관된 객체를 클래스 로딩 시점에서 모두 읽어들이고 싶을 때는 FetchType.EAGER 로 설정을 하면 됩니다. 저희가 사용하고 있는 JPA의 default 값은 EAGER 입니다.
top

  1. Favicon of http://chanwook.tistory.com BlogIcon 찬욱 2007.01.19 18:43 신고 PERM. MOD/DEL REPLY

    JAP의 디폴트는 eager군요!
    Hibernate core에는 3.x부터 lazy에 해당하는 lazy="true"로 되어 있던데..
    차이가 있네요^^'

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2007.01.20 10:17 신고 PERM MOD/DEL

    응 차이가 있네~

Write a comment.


6.2. 필요한 멤버 변수 추가



1. 연관을 맺기 위해서 필요한 필드들을 새로 추가합니다.

Member 모델에 필요한 필드
- Set<MemberGroup> memberGroups;
- Set<Messenger> messengers;

Messenger 모델에 필요한 필드
- Member member;

Group 모델에 필요한 필드
- Set<MemberGroup> memberGroups;

MemberGroup 모델에 필요한 필드
- Member member;
- Group group;

2. 각각의 세터 게터들을 추가합니다.

Alt + Shift + S -> R 단축키 사용.
게터 세터 추가하실 때 팁은.. 새로 추가되는 메소드를 맨 뒤에 생성하기 위해서 커서를 마지막 메소드 아래에 위치 하시고 추가하시면 좋습니다. 게터 세터 메소드를 추가하는 기본 위치 설정이 현재 커서의 위치로 되어 있어서요. :)
top

Write a comment.


6.1. 모델 간의 연관 관계 파악



1. Cardinality 파악
사용자 삽입 이미지

한 명의 멤버는 여러 개의 메신저 정보를 가질 수 있습니다.
하나의 메신저 정보는 한 명의 멤버에 매칭 됩니다.

한 명의 멤버는 여러 개의 그룹 정보를 가질 수 있으며
하나의 그룹은 여러 명의 멤버 정보를 가질 수 있습니다.

But... 둘 사이의 연관으로 인해 Role(그룹에서의 멤버의 역할)이라는 정보와 Joined(멤버가 그룹에 가입한 날짜)와 같은 추가적인 정보가 발생합니다. 이러한 Data는 Member나 Group 어느 한쪽에 포함되는 것 보다는 연관으로 인해 발생하는 Data이기 때문에 연관 개체가 필요한 듯 싶어서 MemberGroup 모델을 만들었습니다.

따라서, 한 명의 멤버는 여러 개의 멤버그룹 정보를 가질 수 있으며
하나의 그룹은 여러 개의 멤버그룹 정보를 가질 수 있습니다.
하나의 멤버 그룸 정보는 한명의 멤버 정보와 한명의 그룹 정보에 매칭이 됩니다.

2. Direction 파악
사용자 삽입 이미지
모든 연관 관계가 전부 양방향성을 가지고 있다고 생각했습니다.
혹시 이 중에서 단방향성을 가지고 있는 것은 없는지 생각해 봐야겠습니다.

top

Write a comment.


6. 연관 관계 매핑하기



1. 모델 간의 연관 관계 파악
1.1. cardinality 파악. 1대1, 1대다, 다대다 확인.
1.2. direction 파악. 단방향, 양방향 확인.

2. 필요한 멤버 변수 추가.
Set, Map, List and so on.

3. JPA(Java Persistent API) 사용하여 모델위에 매핑 정보 표시.
2.1. cardinality 표현.
2.2. direction 표현.
2.3. Fetching Strategy 설정. FetchType.EAGER or FetchType.LAZY

4. 연관 관계를 처리하기 위한 메소드 구현.

5. DAO 테스트에서 연관 관계 테스팅.
top

Write a comment.


5-4. DAO 테스트 만들기



1. test/src 소스 폴더에 keesun.messenger 패키지 안에 MessengerDaoTest 클래스를 생성합니다.
사용자 삽입 이미지
2. 이 클래스는 AbstractTransactionalDataSourceSpringContextDaoTest 이 클래스를 상속 받습니다. 이 클래스는 Spring에 있는 AbstractTransactionalDataSourceSpringContextTests 클래스를 상속하여 만들어진 클래스 입니다.

public class MessengerDaoTest extends AbstractTransactionalDataSourceSpringContextDaoTest{

 

3. 테스트 대상인 MessengerDao를 protected로 변수를 만들고 다음과 같이 bean이 생성됐는지 확인하는 테스트를 만듭니다.

       protected MessengerDao messengerDao;

 

       public void testValidBean(){

             assertNotNull(messengerDao);

       }


테스트는 실패 합니다. 이전 글에서 등록한 빈의 이름이 memberDao로 쓰였네요;; 오타입니다. messengerDao로 수정을 하고 다시 테스트를 하면 통과합니다.

4. Member 객체를 memberDao를 이용해서 DB에 집어 넣는 테스트를 해봅니다. 이 때 MessengerFixture라는 객체를 만들어서 넘겨주는 클래스를 만들어서 사용합니다.

       public void testModel(){

             Messenger m = MessengerFixture.getAMessenger();

             messengerDao.add(m);

             assertTrue(m.getMessengerId()>0);

       }

//MessengerFixture.java

public class MessengerFixture {

 

       public static Messenger getAMessenger() {

             return new Messenger();

       }

}


5. 하지만 이 때 에러가 발생하는데 이유는 필수 요소인(nullable=false) 필드들의 값을 입력하지 안았기 때문에 발생하게 됩니다. 따라서 다음과 같이 수정을 하면 테스트가 통과 합니다.

public void testModel(){

      Messenger m = MessengerFixture.getAMessenger("keesun", "skype");

      messengerDao.add(m);

      assertTrue(m.getMessengerId()>0);

}
//MessengerFixture.java

public static Messenger getAMessenger(String m_id, String m_type) {

     Messenger messenger = new Messenger();

     messenger.setM_id(m_id);

     messenger.setM_type(m_type);

     return messenger;

}

top

  1. Favicon of http://crosscutter.info BlogIcon 지훈 2007.01.11 18:49 PERM. MOD/DEL REPLY

    테스트는 실패 합니다. 이전 글에서 등록한 빈의 이름이 memberDao로 쓰였네요;; 오타입니다.
    -> 재밌게 잘 봤습니다.
    그런데 AbstractTransactionalDataSourceSpringContextDaoTest 무려 51자!
    A49T 라 하는건 어떨까요?

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2007.01.11 23:33 신고 PERM MOD/DEL

    재밌게 봐주셔서 감사합니다.
    하핫 A49T에 대한 제안에 찬성합니다. :)

Write a comment.


5-3. DAO 만들기



1. MessengerDao 인터페이스를 src 소스폴더에 keesun.member.dao 패키지 안에 만듭니다.
사용자 삽입 이미지

2. MessengerDao 인터페이스는 GenericDao 인터페이스를 상속받습니다. GenericDao는 generic을 사용하고 있는데요 첫번째 인자는 클래스 타입이고 두번째 인자는 클래스의 주키값의 타입을 넣습니다.

public interface MessengerDao extends GenericDao<Messenger, Integer>{

 

}


3. MessengerDao를 구현할 MessengerDaoHibernate 클래스를 만듭니다. 이 클래스는 MessengerDao를 implements하고 GenericDao를 구현해 둔 AbstractHibernateGenericDao 클래스를 상속 받습니다.

public class MessengerDaoHibernate extends AbstractHibernateGenericDao<Messenger, Integer>

implements MessengerDao{

}


4. 그러면 에러가 발생하는데 이 때 다음과 생성자를 만들면 에러가 사라집니다. 이것으로 Dao 구현이 끝났습니다.

       protected MessengerDaoHibernate() {

             super(Messenger.class);

       }


5. 방금 만든 dao를 bean으로 등록합니다.

사용자 삽입 이미지

'Hibernate > 주소록 만들기' 카테고리의 다른 글

6.3. 연관 매핑 정보 입력하기  (2) 2007.01.18
6.2. 필요한 멤버 변수 추가  (0) 2007.01.18
6.1. 모델 간의 연관 관계 파악  (0) 2007.01.18
6. 연관 관계 매핑하기  (0) 2007.01.18
5-4. DAO 테스트 만들기  (2) 2007.01.11
5-3. DAO 만들기  (0) 2007.01.11
5-2. 간단한 모델 테스트  (0) 2007.01.11
5-1. 모델 만들기  (0) 2007.01.11
5. 모델, DAO 까지 개발 공정  (0) 2007.01.11
4. CSS 적용  (0) 2007.01.08
3. 화면 만들기  (0) 2007.01.07
top

Write a comment.


5-2. 간단한 모델 테스트



1. 간단한 테스트를 위해서 sandbox.keesun 패키지 안에 MessengerTest.java를 만듭니다.
사용자 삽입 이미지
2. MessengerTest는 AbstractTransactionalDataSourceSpringContextDaoTest 클래스를 상속 받습니다.

public class MessengerTest extends AbstractTransactionalDataSourceSpringContextDaoTest


3. 다음과 같이 코딩합니다.

       public void testCRUD() {

             Messenger m = new Messenger();

             m.setM_id("keesun");

             m.setM_type("skype");

             s.save(m);

             assertTrue(m.getMessengerId() > 0);

       }


DB에 저장이 된다면 객체에 messengerId가 데이타를 가지게 되므로 그것을 확인하는 코드입니다.

테스트를 돌리면 실패합니다. bean을 등록하지 않아서 그렇습니다. 헤헷;
bean은 다음과 같이 applicationContext-dao.xml에 등록합니다.

사용자 삽입 이미지

4. 이제 테스트를 돌리면 pass합니다. :)
사용자 삽입 이미지

'Hibernate > 주소록 만들기' 카테고리의 다른 글

6.2. 필요한 멤버 변수 추가  (0) 2007.01.18
6.1. 모델 간의 연관 관계 파악  (0) 2007.01.18
6. 연관 관계 매핑하기  (0) 2007.01.18
5-4. DAO 테스트 만들기  (2) 2007.01.11
5-3. DAO 만들기  (0) 2007.01.11
5-2. 간단한 모델 테스트  (0) 2007.01.11
5-1. 모델 만들기  (0) 2007.01.11
5. 모델, DAO 까지 개발 공정  (0) 2007.01.11
4. CSS 적용  (0) 2007.01.08
3. 화면 만들기  (0) 2007.01.07
2. 주소록 ERD 수정  (0) 2007.01.06
top

Write a comment.


5-1. 모델 만들기



Messenger 모델을 만들도록 하겠습니다.

1. 프로젝트에서 keesun.model 패키지 안에 Messenger.java파일을 만듭니다.
사용자 삽입 이미지
2. Messenger 객체가 가지고 있어야 할 정보들과 주키 역할을 할 surrogate key[각주:1]를 지정합니다.

public class Messenger {

       Integer messengerId;

 

       String m_id;

 

       String m_type;

}

3. Alt + Shift + S -> R 단축키를 사용해서 먼저 ID에 해당하는 messengerId 에 대한 게터 세터를 만들어 줍니다.
사용자 삽입 이미지
4. 그런 뒤 나머지 프로퍼티에 대한 게터 세터로 같은 방법으로 만들어 줍니다. 이렇게 하는 이유는 주키에 관한 프로퍼티가 제일 위에 만들어지게 하기 위한 것이죠. 헤헷 일종의 센스인듯 합니다.

5. 이제 매핑 정보를 입력합니다. 매핑 정보는 여기서 다룬적이 있기 때문에 패스 합니다. :)
지금은 모델들 간의 연관관계는 신경쓰지 않고 딱 모델신경을 쓰고 있습니다.
  1. natural key와 surrogate key에 대한 내용은 여기를 참조 하세요. [본문으로]

'Hibernate > 주소록 만들기' 카테고리의 다른 글

6.1. 모델 간의 연관 관계 파악  (0) 2007.01.18
6. 연관 관계 매핑하기  (0) 2007.01.18
5-4. DAO 테스트 만들기  (2) 2007.01.11
5-3. DAO 만들기  (0) 2007.01.11
5-2. 간단한 모델 테스트  (0) 2007.01.11
5-1. 모델 만들기  (0) 2007.01.11
5. 모델, DAO 까지 개발 공정  (0) 2007.01.11
4. CSS 적용  (0) 2007.01.08
3. 화면 만들기  (0) 2007.01.07
2. 주소록 ERD 수정  (0) 2007.01.06
1. 주소록 ERD  (0) 2007.01.06
top

Write a comment.


5. 모델, DAO 까지 개발 공정



1. 모델 만들기 - 모델에 두 가지 정보가 들어감.(객체에 관한 정보 + 맵핑에 관한 정보)
-> model bean 등록
2. 간단한 모델 테스트 - 하이버네이트의 Sesssion 객체를 이용한 CRUD 테스트.
3. DAO 만들기 - 인터페이스 사용, GenericDao를 사용하여 만들기.
-> dao bean 등록
4. DAO 테스트 만들기 - 롤백, JUnit의 테스트를 이용할 수 있슴.


'Hibernate > 주소록 만들기' 카테고리의 다른 글

6.1. 모델 간의 연관 관계 파악  (0) 2007.01.18
6. 연관 관계 매핑하기  (0) 2007.01.18
5-4. DAO 테스트 만들기  (2) 2007.01.11
5-3. DAO 만들기  (0) 2007.01.11
5-2. 간단한 모델 테스트  (0) 2007.01.11
5-1. 모델 만들기  (0) 2007.01.11
5. 모델, DAO 까지 개발 공정  (0) 2007.01.11
4. CSS 적용  (0) 2007.01.08
3. 화면 만들기  (0) 2007.01.07
2. 주소록 ERD 수정  (0) 2007.01.06
1. 주소록 ERD  (0) 2007.01.06
top

Write a comment.


4. CSS 적용




사용자 삽입 이미지

얼추 페이지들이 만들어졌습니다. 확장자만 JSP로 바꿨을 뿐 모두 빈껍데기 라는거~

'Hibernate > 주소록 만들기' 카테고리의 다른 글

6.1. 모델 간의 연관 관계 파악  (0) 2007.01.18
6. 연관 관계 매핑하기  (0) 2007.01.18
5-4. DAO 테스트 만들기  (2) 2007.01.11
5-3. DAO 만들기  (0) 2007.01.11
5-2. 간단한 모델 테스트  (0) 2007.01.11
5-1. 모델 만들기  (0) 2007.01.11
5. 모델, DAO 까지 개발 공정  (0) 2007.01.11
4. CSS 적용  (0) 2007.01.08
3. 화면 만들기  (0) 2007.01.07
2. 주소록 ERD 수정  (0) 2007.01.06
1. 주소록 ERD  (0) 2007.01.06
top

Write a comment.


3. 화면 만들기



디자인이 전~혀 없는 완전 HTML 뼈다귀 입니다.
index.html -> memberList.html 로 갑니다.
사용자 삽입 이미지
위에서 Add New Member를 클릭하면 memberInput.html 로 갑니다.

위에서 멤버의 이름을 클릭하면 그 사람의 정보를 자세히 볼 수 있는 memberView.html로 이동합니다.

첫화면에서 검색창에 찾을 키워드를 입력한 뒤 엔터를 치면 search,html로 이동합니다.

'Hibernate > 주소록 만들기' 카테고리의 다른 글

6.1. 모델 간의 연관 관계 파악  (0) 2007.01.18
6. 연관 관계 매핑하기  (0) 2007.01.18
5-4. DAO 테스트 만들기  (2) 2007.01.11
5-3. DAO 만들기  (0) 2007.01.11
5-2. 간단한 모델 테스트  (0) 2007.01.11
5-1. 모델 만들기  (0) 2007.01.11
5. 모델, DAO 까지 개발 공정  (0) 2007.01.11
4. CSS 적용  (0) 2007.01.08
3. 화면 만들기  (0) 2007.01.07
2. 주소록 ERD 수정  (0) 2007.01.06
1. 주소록 ERD  (0) 2007.01.06
top

Write a comment.


2. 주소록 ERD 수정



생각해보니...블로그를 두 개이상 운영하는 경우가 적어서 Member 테이블의 컬럼으로 추가했습니다.
사용자 삽입 이미지
우와~ 테이블 하나 쭐었다~
사용자 삽입 이미지

'Hibernate > 주소록 만들기' 카테고리의 다른 글

6.1. 모델 간의 연관 관계 파악  (0) 2007.01.18
6. 연관 관계 매핑하기  (0) 2007.01.18
5-4. DAO 테스트 만들기  (2) 2007.01.11
5-3. DAO 만들기  (0) 2007.01.11
5-2. 간단한 모델 테스트  (0) 2007.01.11
5-1. 모델 만들기  (0) 2007.01.11
5. 모델, DAO 까지 개발 공정  (0) 2007.01.11
4. CSS 적용  (0) 2007.01.08
3. 화면 만들기  (0) 2007.01.07
2. 주소록 ERD 수정  (0) 2007.01.06
1. 주소록 ERD  (0) 2007.01.06
top

TAG ERD

Write a comment.


1. 주소록 ERD



물개 선생님과 함께 개발할 주소록의 ERD를 그려봤습니다. 프로젝트 일정은 매우 빡쎕니다. 하지만 내기를 했기 때문에 해내야 합니다.
사용자 삽입 이미지
Member와 Group의 관계에 대한 설명
한명의 멤버는 여러개의 그룹에 소속될 수 있으며
하나의 그룹은 여러 명의 멤버를 포함합니다.
이 때 멤버는 그룹에 반드시 속해야 하는 것은 아닙니다.
하지만 그룹은 적어도 2명의 멤버가 있어야 존재 합니다.

Member와 Messengers의 관계에 대한 설명
한명의 멤버는 여러개의 메신저ID를 가질 수 있고
하나의 메신저 ID는 한명의 멤버에 대한 것입니다.

Member와 Bolgs의 관계에 대한 설명
한명의 멤버는 여러개의 블로그를 가지고 있을 수 있고
하나의 블로그는 한명의 관리자가 있습니다.
(팀블로그의 경우 팀블로그 회원이 아닌 팀블로그 마스터가 관리자입니다.)

컬럼 들이랑 주키를 표현한 것인데 FK를 어떻게 나타내는 것인지 몰라서 Member_id 와 같은 식으로 FK를 나타냈습니다.
사용자 삽입 이미지
Spring 으로 개발 중인 주소록은 Member 테이블 달랑 하난데 이거 큰일났군요.

'Hibernate > 주소록 만들기' 카테고리의 다른 글

6.1. 모델 간의 연관 관계 파악  (0) 2007.01.18
6. 연관 관계 매핑하기  (0) 2007.01.18
5-4. DAO 테스트 만들기  (2) 2007.01.11
5-3. DAO 만들기  (0) 2007.01.11
5-2. 간단한 모델 테스트  (0) 2007.01.11
5-1. 모델 만들기  (0) 2007.01.11
5. 모델, DAO 까지 개발 공정  (0) 2007.01.11
4. CSS 적용  (0) 2007.01.08
3. 화면 만들기  (0) 2007.01.07
2. 주소록 ERD 수정  (0) 2007.01.06
1. 주소록 ERD  (0) 2007.01.06
top

TAG ERD

Write a comment.


Transaction

Hibernate/study : 2007.01.02 17:41


사용자 삽입 이미지
[출처 : Hibernate In Action 5.1 Understanding database transactions]

트랜잭션의 특징(ACID)

■ Atomic : 트랜잭션은 하나 이상의 활동들을 묶어놓은 작업의 단위다. 원자성은 이 단위에 있는 모든 활동들이 전부 발생하거나 전부 발생하지 말아야 하는 것을 말한다. 만약 모든 활동들이 원활하게 진행되면 트랜잭션은 성공한다. 그러나 어떤 활동이라도 문제가 발생하면 롤백 하게 된다.

■ Consistent : 트랙잭션이 종료(잘 됐든 안됐든)되면, 시스템은 정상적으로 가동 되는 상태여야 한다. The data should not be corrupted with respect to reality.

■ Isolated : 트랜잭션은 여러명의 유저들이 각각 엉키지 않고 같은 데이타에 접근하는 것이 가능해야 한다. 따라서 트랜잭션은 각각에 독립적이어야 하며 같은 데이타에 동시에 읽거나 쓰는것을 방지해야 한다.(Note that isolation typically involves locking rows and/or tables in a database.) => row나 table별로 locking을 시도 한다고 한느데 이건 마치 자바에서 동기화 처리할 때 객체들의 key나 클래스의 key로 locking할 수 있는 것과 매칭이 됩니다.

■ Durable : 한번 트랜잭션이 완료되면 그 결과는 어떤 종류의 시스템 오류가 발생 하더라도 영구적으로 보존 되어야 한다. 보통 DB나 다른 종류의 Persistent 저장소에 저장하는 일을 포함한다.
[참고 : Spring In Action 5.1.1 Explaining transactions in only four words]

소스코드로 확인 하기

피자의 가격이 음수이면 UnderZeroException이 발생하도록 Pizza의 setPrice를 수정합니다.

public void setPrice(Integer price) throws UnderZeroException {
        if (price < 0) {
            throw new UnderZeroException();
        }
        this.price = price;
    }

그리고 PizzaApp 에서 setPice를 호출 하는 부분을 try-catch 블럭으로 묶습니다.[각주:1] 그리고 catch 블럭에서 tx.rollback()을 호출합니다.
try {
            Pizza pizza = new Pizza();
            pizza.setName("Delicious");
            pizza.setPrice(-100);
            pizza.setSize("Large");
            pizza.setToping("Shrimp & Stake");
            s.save(pizza);
            tx.commit();
        } catch (UnderZeroException e) {
            tx.rollback();
            e.printStackTrace();
        } finally {
            s.close();
        }

이제 위의 트랜잭션은 롤백되서 DB에 저장되지 않습니다.

  1. Alt + Shift + z -> y [본문으로]

'Hibernate > study' 카테고리의 다른 글

Fluent Interface  (2) 2007.01.24
DbUnit  (2) 2007.01.23
Hibernate에서 쿼리 날리는 방법  (0) 2007.01.19
객체들의 상태 변화(in Hibernate)  (2) 2007.01.19
숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
JUnit 으로 Hibernate 테스트  (0) 2007.01.01
Detached Objects  (0) 2007.01.01
Object identity  (2) 2007.01.01
Persistent Object  (0) 2007.01.01
Study To Do List  (2) 2006.12.29
top

  1. Favicon of https://na1217.tistory.com BlogIcon 샤우드 2007.01.02 17:44 신고 PERM. MOD/DEL REPLY

    커헉, 멋 모르고 들어왔다가 어디쓰는 용어야! 를 외치며 침몰됩니다...OTL
    (소스쪽은 언제봐도 이해가 안 되네요..ㅠㅠ)

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2007.01.02 17:55 신고 PERM MOD/DEL

    애니메이션 좋아하시는군요.
    DB와 관련될 때 자주 나오는 단어입니다.

Write a comment.


JUnit 으로 Hibernate 테스트

Hibernate/study : 2007.01.01 19:30


지난번에는 PizzaApp 클래스에서 새로운 피자 객체를 만들고 save()를 사용해서 DB에 insert를 했었습니다.

이번에는 PizzaTest 클래스를 만들고 JUnit을 사용해 봅니다. save()를 사용해서 DB에 피자 한판을 넣어보고 들어갔는지 빼내어 보고 빼낸 것이 null이 아닌지 확인해 봅니다.

연습용이기 때문에 test가 별로 맘에 안드실 수도 있습니다. 저도 별로 테스트가 맘에 들지 않지만 DB에서 데이타를 꺼내오고 JUnit 형태로 만들어 보는것에 목적을 뒀습니다.

public class PizzaTest {

 

       private Session s;

 

       private Transaction tx;

 

       @Before

       public void createSession() {

             ApplicationContext ac = new ClassPathXmlApplicationContext(

                           new String[] { "applicationContext-dao.xml",

                                        "applicationContext-jdbc-datasource.xml" });

             SessionFactory sf = (SessionFactory) ac.getBean("sessionFactory");

 

             s = sf.openSession();

             tx = s.beginTransaction();

       }

 

       @Test

       public void createPizza() {

             Pizza p = new Pizza();

             p.setName("keesun's 2007 pizza");

             p.setPrice(2007);

             p.setToping("happiness");

             p.setSize("2007cm");

 

             s.save(p);

 

             List pizzaList =  s.createQuery("from O_Pizza").list();

             assertNotNull(pizzaList);

       }

 

       @After

       public void close() {

             tx.commit();

             s.close();

       }

}

오.. 잘 돌아갑니다. O_Pizza는 실제 table에는 o_pizza 이렇게 소문자로 들어가 있습니다. postgres 특징인것 같습니다. 하지만 프로그램에서도 o_pizza 이렇게 쓰면 다음과 같은 에러를 볼 수 있습니다.

DB의 table이름을 쓰지 말고 @Entity의 name속성에 지정한 이름으로 사용해야 합니다.


 

'Hibernate > study' 카테고리의 다른 글

DbUnit  (2) 2007.01.23
Hibernate에서 쿼리 날리는 방법  (0) 2007.01.19
객체들의 상태 변화(in Hibernate)  (2) 2007.01.19
숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
JUnit 으로 Hibernate 테스트  (0) 2007.01.01
Detached Objects  (0) 2007.01.01
Object identity  (2) 2007.01.01
Persistent Object  (0) 2007.01.01
Study To Do List  (2) 2006.12.29
Transient Object  (0) 2006.12.28
top

Write a comment.


Detached Objects

Hibernate/study : 2007.01.01 18:51


참조 : Hibernate In Action 4.1.3 Detached Obejcts

트랜잭션이 완료되면 Persistence Manager과 연관이 있었던 객체는 그대로 남아있게 된다. 하이버네이트에서는 Session의 close()메소드를 호출하면 그 연관이 사라지며 이 상태는 DB과 동기화 되어 있지 않은 상태(동기화 된적이 있는 상태)로 Detached라고 한다.

하이버네이트에서 이 객체들은 새로운 persistent manager와 연관을 맺고 새로운 트랙잭션에서 재사용이 가능하다.=>다시 Persistent 객체가 될 수 있다.

DTO 패턴(안좋은 패턴 인듯..)을 피할 때 사용할 수 있다. <= 8장에서 살펴본다고 함.

evict()메소드를 호출하여 detached 상태가 될 수 있지만 cache 관리를 위해서 사용함으로 일반적인 방법은 아니다. Session의 close()를 사용하거나 원격으로 보내야 해서 직렬화 했을 때 모든 객체들이 detached된다.

사용자 삽입 이미지

'Hibernate > study' 카테고리의 다른 글

Hibernate에서 쿼리 날리는 방법  (0) 2007.01.19
객체들의 상태 변화(in Hibernate)  (2) 2007.01.19
숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
JUnit 으로 Hibernate 테스트  (0) 2007.01.01
Detached Objects  (0) 2007.01.01
Object identity  (2) 2007.01.01
Persistent Object  (0) 2007.01.01
Study To Do List  (2) 2006.12.29
Transient Object  (0) 2006.12.28
JPA를 필드 위에 써보기  (0) 2006.12.28
top

Write a comment.


Object identity

Hibernate/study : 2007.01.01 17:44


참조 : Hibernate In Action 3.4. Understanding object identity

■ Object identity : == 으로 확인하며 객체가 메모리에 같은 위치에 있다.

■ Object equality : equals(Object o)로 확인하며 객체가 가지고 있는 속성들의 값이 같다. Object class의 equals(Obejct o)메소드는 Object identity를 확인하기 때문에 overriding하여 사용해야 한다. (String class는 값을 비교하도록 overriding 되어있습니다.)

Database identity : 관계형 DB에 저장되어 있는 객체들이 같은 테이블에 있고 주키 값이 같으면 같은 row이며 동등하다.


하이버네이트에서 DB에 있는 주키를 가져오는 방법으로 public 게터를 사용하고 주키의 값이 바뀌면 안되기 때문에 private 쎄터를 사용한다.

public class Category {
private Long id;
...
    public Long getId() {
    return this.id;
    }
    private void setId(Long id) {
    this.id = id;
      }
  ...
}

주키(primary key) 선택 조건 세가지
■ The value or values are never null.
■ Each row has a unique value or values.
■ The value or values of a particular row never change.

후보키(cadidate key) = 주키가 될 수 있는 식별자들.(유일 한 값들)

natural primary key = 주키에 비즈니스 의미가 포함되어 있는 키. 주민등록번호 중 두번째 단어의 첫 숫자는 성별을 나타낸다.(하리수의 경우 이 수가 변하는데 이때 주키의 조건 중 세번 째 것을 위반하게 됩니다.)

surrogate key(synthetic identifiers) = 아무 의미가 담겨져 있지 않은 주키. 이걸 쓰는 것을 강추하며 하이버네이트에 미리 만들어 놓은 다음과 같은 것들이 있다.
사용자 삽입 이미지
이중에서 예제에서는 sequence를 사용했었습니다.


'Hibernate > study' 카테고리의 다른 글

객체들의 상태 변화(in Hibernate)  (2) 2007.01.19
숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
JUnit 으로 Hibernate 테스트  (0) 2007.01.01
Detached Objects  (0) 2007.01.01
Object identity  (2) 2007.01.01
Persistent Object  (0) 2007.01.01
Study To Do List  (2) 2006.12.29
Transient Object  (0) 2006.12.28
JPA를 필드 위에 써보기  (0) 2006.12.28
@Column 조사  (2) 2006.12.28
top

  1. Favicon of http://chanwook.tistory.com BlogIcon 찬욱 2007.01.05 20:13 신고 PERM. MOD/DEL REPLY

    언제 트랙백을 달으셨데요~ 답글도 하나 달아주시지 ~ㅋ 몰랐네요.
    저도 한 방 쏩니다.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2007.01.05 20:37 신고 PERM MOD/DEL

    ㅇㅇ아침에 달아놨지. 요즘 티스토리에서 테터로 트랙백이 안쏴져서 재미가 없던 참이라.. 틈나는대로 쏘고 있다. ㅋㅋ

Write a comment.


Persistent Object

Hibernate/study : 2007.01.01 17:08


참조 : Hibernate In Action 4.1.2 Persistent Obejct

Persistent 객체는 Database indentity를 가지고 있는 객체이다.

Persistent Maneger(Hibernate의 Session)에 의해 save()가 호출된 객체 or 이미 Persistent Manager와 연관이 있는 Persistent 객체에 의해 참조된 객체. <= persistent instances are always associated with a Session and are transactional.

Persistent 객체는 트랜잭션이 끝날 때 까지 DB와 동기화된다. 트랜잭션이 커밋될 때 메모리에 있던 객체의 상태가 SQL쿼리를 이용해서 DB로 보내진다. 이런 처리는 트랜잭션이 끝날 때가 아니더라도 발생할 수 있다.

"new"라는 상태는 Persistent 객체가 주키를 가졌지만 아직 DB에 들어가지 않은 상태다. 동기화가 발생하기 전까지 "new"상태가 유지된다.

automatic dirty checking 은 트랜잭션 내에서 어떤 Persistent 객체가 수정이 되었는지 찾아내는 ORM 소프트웨어의 전략이다. 하이버네이트는 애플리케이션에서 안보이게(transparent) persistent 상태의 변화를 가능한한 나중에 DB에 반영을 하는데 이것을 transparent transaction-level write-behind 라고 한다.

하이버네이트는 어떤 속성이 변했는지 알 수 있으며 따라서 특정 컬럼만 update하는 것이 가능하다. => 이래서 1-7. 레코드 update하기 에서 session.update(pizza);를 하지 않아도 가능 했던것 같습니다.

delete()를 호출하게 되면 DB table에서 객체에 해당하는 row가 삭제 되며 transient 객체가 된다.

사용자 삽입 이미지


'Hibernate > study' 카테고리의 다른 글

숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
JUnit 으로 Hibernate 테스트  (0) 2007.01.01
Detached Objects  (0) 2007.01.01
Object identity  (2) 2007.01.01
Persistent Object  (0) 2007.01.01
Study To Do List  (2) 2006.12.29
Transient Object  (0) 2006.12.28
JPA를 필드 위에 써보기  (0) 2006.12.28
@Column 조사  (2) 2006.12.28
JPA(Java Persistent API)가 뭐지..  (2) 2006.12.28
top

Write a comment.


Study To Do List

Hibernate/study : 2006.12.29 15:29


Hibernate 기초 개념
@Transient
persistence : DB에 메모리에 떠도는 데이터를 영구히 보관한다는 개념
Alternatives for Persistence : SQL은 기본이고, JDBC 직접 조작, DAO 개발, EJB의 EntityBean 사용.. Hibernate,TopLink 같은 ORM.. 등등
그 중에서 왜 하필 ORM을 쓰냐.. 는 질문에 대한 답 : Object/Relational Mismatch
그럼 ORM 중에서 왜.. Hibernate냐 : POJO 기반의 Transparent Persistency를 지원한다
참고할 사이트 : http://javacan.madvirus.net/ (여기서 hibernate 검색 후 나오는 시리즈 물 참조)

DB 기초 개념
join과 같은...

친절한 선생님
을 만나서 공부운이 트였습니다. 감사합니다. 저는 내년에도 더욱 열심히 공부하는 학생이 되겠습니다. 기선아 파이팅!!!

'Hibernate > study' 카테고리의 다른 글

숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
JUnit 으로 Hibernate 테스트  (0) 2007.01.01
Detached Objects  (0) 2007.01.01
Object identity  (2) 2007.01.01
Persistent Object  (0) 2007.01.01
Study To Do List  (2) 2006.12.29
Transient Object  (0) 2006.12.28
JPA를 필드 위에 써보기  (0) 2006.12.28
@Column 조사  (2) 2006.12.28
JPA(Java Persistent API)가 뭐지..  (2) 2006.12.28
top

  1. Favicon of http://seal.tistory.com BlogIcon 물개선생 2006.12.29 20:04 PERM. MOD/DEL REPLY

    어찌나 부지런하신지.. ^^;
    저도 연말에 푹~ 쉬면서 공부할 목차를 잘 정비해 보겠습니다.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2006.12.29 20:20 신고 PERM MOD/DEL

    ^^;; 에고 부지런 하긴요~
    공부할 것들이 이렇게 많을 줄 몰랐어요.
    열심히 해서 누가 되지 않도록 하겠습니다. :)

Write a comment.


Transient Object

Hibernate/study : 2006.12.28 19:51


참조 : Hibernate In Action 4.1.1

Transient Object

new라는 키워드를 사용하여 생성된 객체는 그 즉시 persistent 상태가 아니다. 이 상태는 transient상태이며 이것은 DB의 테이블의 어떤 레코드와도 연관이 없으며 따라서 언제라도 참조를 잃게 되면(null 이 되면) 상태에 대한 정보를 잃게 된다.

트랜잭션 관리의 대상이 되지 않는다. 따라서 Transient 객체에는 롤백 기능을 제공하지 않는다.

transient 상태의 객체가 save()의 대상이 되거나 다른 persistent 상태의 객체로 부터 참조되는 경우에 persistent 상태가 된다.

사용자 삽입 이미지

'Hibernate > study' 카테고리의 다른 글

숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
JUnit 으로 Hibernate 테스트  (0) 2007.01.01
Detached Objects  (0) 2007.01.01
Object identity  (2) 2007.01.01
Persistent Object  (0) 2007.01.01
Study To Do List  (2) 2006.12.29
Transient Object  (0) 2006.12.28
JPA를 필드 위에 써보기  (0) 2006.12.28
@Column 조사  (2) 2006.12.28
JPA(Java Persistent API)가 뭐지..  (2) 2006.12.28
top

TAG Transient

Write a comment.


JPA를 필드 위에 써보기

Hibernate/study : 2006.12.28 19:01


기존 코드는 getter위에 어노테이션들을 적용했었는데요. 필드 위에 써도 된다고 합니다. 그래서 한번 실험 삼아 해봅니다. 먼저 pgAdmin으로 기존에 있던 테이블을 지웠습니다.
사용자 삽입 이미지
그리고 Pizza 클래스를 다음과 같이 어노테이션들의 위치를 getter위에서 필드 위로 이동시켰습니다.
    @Id
    @GeneratedValue(generator = "Pizza_PizzaId_Seq", strategy = GenerationType.AUTO)
    private Integer pizzaId;

    @Column(nullable = false, length = 50)
    private String name;

    @Column
    private Integer price;

    @Column(length = 50)
    private String size;

    @Column(nullable = false)
    private String toping;

그리고 PizzaApp를 실행했습니다.
사용자 삽입 이미지
오호 되는군요~

어라! 근데 table이 두 개 입니다. Member 테이블 까지 생겼네요. Member 모델과 MemberApp라는 어플리케이션을 만들어서 실험해본 적이 있었는데 MemberApp를 실행하지 않았는데도 Member 테이블이 생긴이유는...

사용자 삽입 이미지
applicationContext-dao.xml의 윗 부분과 같이 설정해 두었기 때문인듯 합니다. 저기서 어노테이션이 붙은 클래스들을 전부 읽어 가기 때문에 PizzaApp가 실행되면서 Member 테이블 까지 만들어 준 것으로 결론이 지어집니다.

'Hibernate > study' 카테고리의 다른 글

숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
JUnit 으로 Hibernate 테스트  (0) 2007.01.01
Detached Objects  (0) 2007.01.01
Object identity  (2) 2007.01.01
Persistent Object  (0) 2007.01.01
Study To Do List  (2) 2006.12.29
Transient Object  (0) 2006.12.28
JPA를 필드 위에 써보기  (0) 2006.12.28
@Column 조사  (2) 2006.12.28
JPA(Java Persistent API)가 뭐지..  (2) 2006.12.28
top

Write a comment.


@Column 조사

Hibernate/study : 2006.12.28 18:49


참조 : http://java.sun.com/javaee/5/docs/api/javax/persistence/Column.html
JPA에 포함되어 있는 어노테이션으로 POJO위에 해당 필드가 DB의 컬럼과 매핑이 되도록 설정하는데 사용했었습니다.

사용할 수 있는 속성들로는 다음과 같은 것들이 있습니다.
사용자 삽입 이미지

위 속성들은 전부 Optional 이기 때문에 설정하지 않아도 됩니다. 그럴 때는 각 속성들의 default값들로 설정됩니다.

columnDefinition은 해당 컬럼을 생성할 때의 SQL이라고 하는데 잘 모르겠네요. 기본값은 ""
inserttable은 inset가 가능한지 여부를 나타내며 기본 값은 true
length는 해당 컬럼의 길이며 기본 값은 255
name은 이 필드와 매칭 될 컬럼의 이름이며 기본 값은 필드 명으로 들어갑니다.(기본 값은 ""이렇게 써있는데..)
nullable은 필드가 null값을 허용하는지 여부이며 기본 값은 true
precision과 scale은 실수를 나타낼 때 사용하며 기본 값은 0
table은 컬럼이 어느 테이블에 만들어질지 정하는 것 같습니다. 기본값은 primary table이라고 적혀있는데 현재 소속된 클래스의 테이블로 들어가는 것 같습니다.
unique는 해당 컬럼이 uniauq key인지 나타내며 기본값은 false
updatable은 UPDATE sql이 사용가능한지 여부이며 기본값은 true

전부 기본적인 세팅이라서 마치 Java의 멤버 변수들의 기본값 처럼 쉽게 머릿속에 들어옵니다.
하지만 몇몇은 기본값이 "" 라고 되어 있지만 그렇치 않은 것들이 있네요.
columnDefinition(요건 뭔지 잘 모르겠지만), name, table은 기본 값이 ""가 아니고 필드명과 필드가 속해있는 클래스의 테이블명이 되는 것 같습니다.

'Hibernate > study' 카테고리의 다른 글

숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
JUnit 으로 Hibernate 테스트  (0) 2007.01.01
Detached Objects  (0) 2007.01.01
Object identity  (2) 2007.01.01
Persistent Object  (0) 2007.01.01
Study To Do List  (2) 2006.12.29
Transient Object  (0) 2006.12.28
JPA를 필드 위에 써보기  (0) 2006.12.28
@Column 조사  (2) 2006.12.28
JPA(Java Persistent API)가 뭐지..  (2) 2006.12.28
top

TAG @Column
  1. 이은주 2007.01.09 10:00 PERM. MOD/DEL REPLY

    columnDefinition 은 컬럼에 대한 정의를 나타내는 거 같은데요..
    name : 이름 이런식으로..

    Favicon of http://whiteship.tistory.com/ BlogIcon 기선 2007.01.09 10:22 PERM MOD/DEL

    흠..네엡 그런 것 같습니다.

    @Column이 XML로 설정할 때는<property>랑 매칭이 되는 것 같은데요. 아마.. columnDefinition은 <property>에서 지정할 수 있는 속성들 중에서 formula와 매칭되는 것 같습니다.

    SQL로 직접 컬럼의 특징을 정해 줄 수 있는 것이 아닐런지..싶네요 :)

    formula에 대해서는
    http://www.hibernate.org/hib_docs/v3/reference/en/html/mapping.html
    여기 중간 쯤에 property에 관한 설명에서 참조할 수 있을 것 같습니다.

Write a comment.


JPA(Java Persistent API)가 뭐지..

Hibernate/study : 2006.12.28 17:48


지난 스터디 때 처음 들어본 단어 JPA[각주:1]를 공부해야 한다는 말씀을 듣었습니다. 설명도 살짝 들었습니다.

EJB와 관련지어 설명해 주셨는데 EJB를 공부해본 적도 없고 경험이 없기 때문에 이해하지 못하고 외울 수 밖에 없었습니다. EJB의 Entity bean과 연관지어 설명해 주신 것이 기억이 나서 찾아 보았습니다.

위키피디아에 있는 Entitry Bean의 정의입니다.
An Entity Bean is a type of Enterprise JavaBean, a server-side Java EE component, that represents persistent data maintained in a database. An entity bean can manage its own persistence (Bean managed persistence) or can delegate this function to its EJB Container (Container managed persistence). An entity bean is identified by a primary key. If the container in which an entity bean is hosted crashes, the entity bean, its primary key, and any remote references survive the crash.

In EJB 3.0, entity beans were superseded by the Java Persistence API.
Entity Bean은 database에서 관리되는 persistent data를 java 프로그램에서 표현하기 위해 사용되는 하나의 타입인 것 같습니다. 이 빈들은 주키로 관리가 되는데...EJB 3.0에서는 JPA에 의해 대체 됐다고 하는군요.

위키피디아에서 JPA를 찾아봤습니다.
The Java Persistence API, sometimes referred to as JPA, is a Java programming language framework that allows developers to manage relational data in Java Platform, Standard Edition and Java Platform, Enterprise Edition applications.

Java 플렛폼 기반으로 관계형 Data를 프로그램에서 다룰 때 사용하는 프레임웍이라는 짧은 설명입니다.
세가지 구성요소를 들고 있는데 다음과 같습니다.(Persistence consists of three areas:)
    * the API, defined in the javax.persistence package
    * the Java Persistence Query Language
    * object/relational metadata


좀더 자세한 내용을 찾고 싶어 sun에서 찾아 보았습니다.
http://java.sun.com/developer/technicalArticles/J2EE/jpa/index.html
J2EE tutorial에서 JPA 부분
J2EE API에서 JPA부분


  1. 물론 처음 들어본 단어는 이 밖에도 많았지요. [본문으로]

'Hibernate > study' 카테고리의 다른 글

숙제  (0) 2007.01.19
Transaction  (2) 2007.01.02
JUnit 으로 Hibernate 테스트  (0) 2007.01.01
Detached Objects  (0) 2007.01.01
Object identity  (2) 2007.01.01
Persistent Object  (0) 2007.01.01
Study To Do List  (2) 2006.12.29
Transient Object  (0) 2006.12.28
JPA를 필드 위에 써보기  (0) 2006.12.28
@Column 조사  (2) 2006.12.28
JPA(Java Persistent API)가 뭐지..  (2) 2006.12.28
top

TAG JPA
  1. Favicon of https://jjaeko.tistory.com BlogIcon 째코 2008.01.17 13:04 신고 PERM. MOD/DEL REPLY

    제목이 같은건 고의가 아닙니다 -0-;;
    2006년 12월달이면 제가 자바 시작하고 얼마 지나지 않았을 때인데 저랑 너무 많은 차이가 나네요

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2008.01.17 20:58 PERM MOD/DEL

    에고 이런 글을 썼는지도 잊어버렸었는데 감사합니다. JPA가 저런 뜻이었군요;

Write a comment.


1-8. Hibernate Application 에서 사용되는 객체의 상태



사용자 삽입 이미지

Hibernate In Action 4.1.1 Transient Object 처음에 나오는 그림입니다. Hibernate에서 사용되는 객체의 상태 변화를 보여주고 있습니다.
  • Transient는 DB와 아무 연관이 없는 상태입니다.
  • Persistent는 DB와 동기화 되어 있는 상태입니다.
  • Detached는 DB와 동기화 된 적이 있는 상태입니다.
소스코드와 연관 시켜 보겠습니다.
        Pizza pizza = new Pizza();
        pizza.setName("ines's pizza");
        pizza.setPrice(10000);
        pizza.setSize("Large");
        pizza.setToping("Kimchi");

        s.save(pizza);

        pizza.setPrice(15000);

        tx.commit();
        s.close();

        pizza.setPrice(20000);

위 소스크드와 그림을 보시면서 Pizza 객체의 상태를 추적해 보겠습니다. 먼저 new를 하여 객체를 생성하게 되면 이 객체는 transient 상태가 됩니다. 그 후에 s.save(pizza);를 하게 되면 Persistent 상태가 되는데 그렇기 때문에 이 전 글에서 s.update(pizza); 를 호출하지 않아도 DB와 동기화 되어 있는 상태이기 때문에 update가 된 것 같습니다. 그 뒤 s.close()를 호출하면 그 뒤 부터는 DB와 동기화 된 적은 있지만 현재는 그렇지 않은 Detached 상태가 됩니다.
new를 만나면 Transient => save() 이후 부터는 Persistent => close() 이후 부터는 Detached 상태 입니다.

Transient 상태와 Detached 상태의 차이점은 Transient 상태에서 Pizza의 pizzaId라는 속성은 null인 상태입니다. 하지만 Detached 상태는 DB와 동기화 된 적이 있기 때문에 pizzaId 속성에 값을 가지고 있습니다.

top

Write a comment.


1-7. 레코드 update 하기



PizzaApp의 내용을 다음과 같이 수정합니다.
Pizza pizza = new Pizza();
        pizza.setName("yuonghoe's pizza");
        pizza.setPrice(10000);
        pizza.setSize("Large");
        pizza.setToping("Pepperoni");

        s.save(pizza);

        pizza.setPrice(15000);
        s.update(pizza);
처음에 가격을 만원으로 했다가 너무 낮아서 만오천원으로 올리고 s.update(pizza); 메소드를 사용하여 update를 합니다.

실행시키면 콘솔 창에 다음과 같이 출력됩니다.
Hibernate: select nextval ('Pizza_PizzaId_Seq')
Hibernate: insert into O_Pizza (toping, price, name, size, pizzaId) values (?, ?, ?, ?, ?)
Hibernate: update O_Pizza set toping=?, price=?, name=?, size=? where pizzaId=?

사용자 삽입 이미지

DB를 확인해 본 결과 15000원으로 update된 것을 확인 할 수 있습니다.

PizzaApp에서 작성한 코드에서 s.update(pizza);를 삭제하고 다음과 같이 입력해 보겠습니다.
        Pizza pizza = new Pizza();
        pizza.setName("chanwook's pizza");
        pizza.setPrice(10000);
        pizza.setSize("Large");
        pizza.setToping("Kimchi");

        s.save(pizza);

        pizza.setPrice(15000);

s.update(pizza); 가 빠진것을 제외하면 다른 부분은 거의 동일합니다. 이 것을 실행시키면 콘솔창에 다음과 같이 출력이 되고 DB에서 확인을 해도 역시 update 된 것을 확인할 수 있습니다.
Hibernate: select nextval ('Pizza_PizzaId_Seq')
Hibernate: insert into O_Pizza (toping, price, name, size, pizzaId) values (?, ?, ?, ?, ?)
Hibernate: update O_Pizza set toping=?, price=?, name=?, size=? where pizzaId=?

사용자 삽입 이미지

왜 이럴지는 HIA 4장에 나오는 그림을 보며 생각해 보겠습니다.
top

TAG Update

Write a comment.


1-6. 모델 클래스 수정하기



Pizza 클래스에 새로운 필드를 추가해 봅니다.

toping이라는 멤버를 추가하고 역시 어노테이션을 사용하여 @Column으로 지정해 줍니다. 그리고 getter, setter를 만들어 준뒤 PizzaApp 클래스에 적당한 값들로 세팅해 주고 save를 해봅시다.

그리고 PizzaApp를 실행 시키면 다음과 같이 새로운 필드가 생기고 기존에 있던 data들은 새로운 필드에 null값이 들어간 상태로 바뀝니다.

Hibernate: select nextval ('Pizza_PizzaId_Seq')
Hibernate: insert into O_Pizza (toping, price, name, size, pizzaId) values (?, ?, ?, ?, ?)

사용자 삽입 이미지

여기서 궁금한건..만약에 새로 만든 필드의 Column 속성에서 nullable을 false로 하면 어떻게 될까요? 해보면 되겠죠?

pgAdmin에서 table을 전부 날려버리고 Pizza 클래스에 추가했던 toping 멤버를 삭제하고 게터와 세터로 삭제합니다. 그리고 name, size, price만 넣어 줍니다.
사용자 삽입 이미지

이 상태에서 이제 다시 Pizza 클래스에 Toping을 추가하고 이번에는 @Column(nullable=false)로 설정을 해줍니다. 그리고 PizzaApp에서는 새로운 레코드를 추가합니다.
그리고 실행을 하면 다음과 같은 메시지가 콘솔창에 출력됩니다.

Hibernate: select nextval ('Pizza_PizzaId_Seq')
Hibernate: insert into O_Pizza (toping, price, name, size, pizzaId) values (?, ?, ?, ?, ?)

엇... DB로 확인해 봤더니 toping이라는 컬럼이 추가 되었고 새로운 레코드도 입력 되었습니다. 하지만 기존에 있던 레코드는 새로 생긴 컬럼이 null로 되어있습니다.

사용자 삽입 이미지

오호~~~table을 생성하는 쿼리를 살펴봤더니 toping 컬럼을 만들 때 not null을 넣지 않았군요. Hibernate 가 마치 '이정도 쯤이야' 하며 으쓱해 하는 기분이군요. 새로 추가되는 필드는 nullable=false로 하더라도 무시 됩니다. 그리고 그렇게 처리하는 것이 논리적인 것 같습니다.

사용자 삽입 이미지

top

Write a comment.


1-5. 모델 사용하기



앞에서 만든 모델을 사용하는 간단한 어플리케이션을 만들기 위해 src밑에 app라는 패키지를 만들고 그안에 PizzaApp 클래스를 만듭니다.

package app;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class PizzaApp {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext(
                new String[] { "applicationContext-dao.xml",
                        "applicationContext-jdbc-datasource.xml" });
        SessionFactory sf = (SessionFactory) ac.getBean("sessionFactory");

        Session s = sf.openSession();
        Transaction tx = s.beginTransaction();

        //TODO 할일

        tx.commit();
        s.close();
    }
}

녹색 부분은 Spring을 사용하여 session 팩토리를 받아옵니다. 역시 전 Session Factory도 처음 보는 것이기 때문에 이 부분도 공부가 필요합니다.
파란색 부분은 세션 팩토리를 사용하여 세션을 열고 닫는 부분입니다.
보라색 부분은 세션으로 부터 트랜잭션을 시작하고 완료 시키는 부분입니다.

세션을 열고 트랜잭션 시작한 뒤에~ 하고 싶은 일을 하면 됩니다. 먼저 Pizza 객체를 생성하여 DB에 저장을 해봅니다.
        Pizza pizza = new Pizza();
        pizza.setName("keesun's pizza");
        pizza.setPrice(200);
        pizza.setSize("BIG");
위와 같이 코딩을 하고 저장을 하겠다는 의미로
    s.save(pizza);
이렇게 하면 DB에 들어가게 될 것입니다.

기대를 품고 실행을 하면 다음과 같은 에러를 볼 수 있습니다.

postgres JDBC를 빌드 경로에 추가하지 않아서 발생한 에러입니다. 적절한 조취를 취한 뒤[각주:1] 다시 실행시키면~

1-3. 기본 설정 하기
에서 유심히 보신 분은 눈치 채셨겠지만 applicationContext-dao.xml 의  sessionBean 설정에서 '뭔가 들어가야 할 부분'에 다음의 코드를 넣습니다.
<property name="annotatedClasses">
            <list>
                <value>model.Pizza</value>
            </list>
</property>

어노테이션이 사용된 클래스를 등록해 주는 것 같습니다. 그리고 이제 프로그램을 실행시키면 커맨드 창에서 다음의 메시지를 확인 할 수 있습니다.

Hibernate: select nextval ('Pizza_PizzaId_Seq')
Hibernate: insert into O_Pizza (price, name, size, pizzaId) values (?, ?, ?, ?)

그리고 DB에서 확인하면 다음과 같이 Table이 생기고 data가 들어간 것을 확인 할 수 있습니다.

사용자 삽입 이미지

정말 마술 같은 쑈입니다. :) DB와 SQL에 손도 안대고 table을 만들고 데이타를 넣다니..허허허;;;
  1. postges설치 경로 / 8.1 / jdbc / postgresql-8.1-405.jdbc3.jar 를 lib에 복사한 뒤 빌드 경로에 추가 해줌 [본문으로]
top

  1. Favicon of http://chanwook.tistory.com/ BlogIcon 찬욱 2006.12.27 10:30 PERM. MOD/DEL REPLY

    부러워요!!
    혼자 이런걸 하다니!

    안그래도 Hibernate 하면서 annotation 으로 공부하고 싶었는데 눈팅으로 공부하면 되겠군요..
    으흐흐..

    Favicon of http://whiteship.tistory.com/ BlogIcon 기선 2006.12.27 11:33 PERM MOD/DEL

    오픈시드에 내가 체험한 강의가 그대로 올라와 있으니 그걸 보면되지.
    아직 정리를 못한 내용도 그곳에 올려진 파일에 있어.ㅋㅋ

Write a comment.


1-4. 모델 만들기



src에 model패키지를 추가하고 간단한 POJO 클래스를 만들어 봅니다.

현재 살짝 졸린데 배까지 고픈 관계로 Pizza 클래스를 만들기로 하겠습니다. 속성으로는 고유한 값에 해당하는 pizzaId, size, name, price 이렇게 네가지가 있습니다.

매우 단순한 클래스가 만들어졌습니다. 이제 이 클래스에 어노테이션을 적용합니다. 어노테이션을 적용하게 되면 테이블과 매핑이 이뤄집니다.

사용자 삽입 이미지
이때 주의 할 점은 방언에 해당하는 org.hibernate.annotations에 있는 어노테이션 말고 차후 확장성을 고려하여 javax.persistence에 있는 어노테이션을 사용하기 입니다.

각 어노테이션에 지정할 수 있는 속성이 보고 싶을 땐 이클립스에서 원하는 어노테이션에서 f4를 누르면 왼쪽 hierarchy 창에서 보입니다.

여기서 사용한 어노테이션으로는 Entity, Id, Column, SequenceGenerator, GeneratedValue입니다. 각각에서 사용가능한 속성들에 대한 공부도 필요할 것 같습니다.
top

Write a comment.




: 1 : ··· : 3 : 4 : 5 : 6 : 7 :