Whiteship's Note


OSIV 사용시 주의 할 것

모하니?/Coding : 2008.05.11 23:32


OSIV 기본 지식 - 참조 http://www.hibernate.org/43.html

먼저 OSIV는 Open Session In View 패턴의 약자로 보통 OSIV 필터나 인터셉터 중 하나를 사용합니다. 사용하는 이유는? 뷰 랜더링을 완료 할 때까지 세션을 유지하기 위함이다. 세션이 닫힌 상태에서 프록시로 읽어온 콜렉션이나 레퍼런스의 속성에 접근하면 LazyInitializationException이 발생하고, 이 해결책으로 뷰를 랜더링 하기 위한 세션을 새로 열수도 있겠지만, 이 방법은 그리 좋치 않다. 일단 이 작업이 이전 세션에 포함되어야 적당하지 개별적인 작업 단위로 보기는 뭐시기하기 때문이다. 요청이 오면 새로운 Session과 Transaction을 생성하고 응답을 클라이언트에 보내기 직전에 Transaction을 커밋하고 Session을 닫는게 가장 단순한 OSIV의 기능이 되겠다.

여기에 Conversation을 고려하고 서브 트랜잭션(서브 트랜잭션을 지원한다면, 두 개의 트랜잭션으로 나워서 읽고/쓰기 작업을 하는 트랜잭션과 뷰에 랜더링 하는 읽기 전용 트랜잭션으로 쪼개는 것이 좋다. 쓰기롹을 빨리 반환할 수 있으니까.)그리고 예외 처리까지 고려해서 인터셉터나 필터를 만들어야 한다.

하이버네이트의 update() 기본 지식 - 참조 http://whiteship.tistory.com/1616

Persistent Context에 이미 Persistent 상태로 로딩되어 있는 객체가 있을 때, 그와 같은 id를 가진 객체를 또 다시 Persistent Context에 붙이려는 시도가 있을 때 NonUnique뭐시기 에러가 발생합니다. 흔히 Detached 상태의 객체를 update() 메소드를 사용하여 Persistent Context에 Reattch를 시도할 때 이런 예외가 발생할 수 있는데, 그럴 때는 merge를 하여 기존의 Persistent Context에 있는 객체의 값을 새로운 객체 값으로 덮어쓸 수도 있지만 이 때 merge() 메소드로 넘겨준 객체의 상태가 Persistent 상태로 변하지 않고 그대로 유지 되되며, merge()가 반환하는 레퍼런스와 기존에 Persistent Context에 존재하는 레퍼런스 두 개가 동일한 데이터를 가리키게 됨으로 프로그래밍에 혼란을 줄 수 있다. 따라서 해당 객체를 evict()를 사용하여 Persistent Context에서 빼내고 update()의 인자로 넘겨준 객체를 Persistent 상태로 만드는 것이 적절한 해결책일 것이다.

자... 이제 OSIV 필터를 사용하고 있을 때 Validator에 다음과 같은 코드가 있습니다.

public class MemberValidator implements Validator {
...
  @Autowired
  MemberService memberService;

  ...
  Member memberCommand = (Member)command;
  Member existingMember = memberService.get(memberCommand.getEmail());
  if(existingMember != null)
    errors.reject("email", "duplicated", "해당 이메일은 이미 가입되어 있습니다.");
  ...
 
...
}

위의 코드는 일단 상당히 별로 입니다. memberSerivce.isExistingEmail(memberComman); 라는 메소드를 만들어서 그 반환값을 가지고 조건을 거는게 더 좋은 API로 생각됩니다. MemberService의 isExistingEmail() 에서 데이터베이스에 접근하는 코드는 memberDao를 사용해서 Member 객체를 가져오고 지지고 볶는게 훨씬 좋습니다. 그리고 사실 저런 경우 멤버 객체를 가져올 필요도 없고 레코드 갯수만 가져오면 되겠죠. 그런데 그냥.. 여기서는 그냥. 저렇게 코딩을 했다고 가정하겠습니다.

이런 상황에서 방금 말씀드린 코드의 책임 문제를 떠나 정말 중대한 문제가 있습니다.

그 문제가 뭔지는 알 갈쳐드립니다. 비밀이에요. (ㅋㅋ이미 문제의 원인과 해결책은 위의 기본 이론에 다 설명이 되어 있습니다.) 토비 사부님께 듣기로는 물개 선생님께서도 이와 같은 문제를 겪은 적이 있다는 얘기를 들었습니다. 이런 해프닝을 겪으면서 느낀 건 아무리 공부를 해도 역시.. 코딩을 해봐야... 알 수 있고.. 문제의 원인과 그 원인 해결책은 다시 공부를 해야 이해할 수 있다는 것입니다.

공부와 코딩을 떨어질래야 떨어질 수 없는 친구인거죠.
top

Write a comment.


Really easy field validation 사용하기

모하니?/Coding : 2007.04.18 01:14


012

흐흐흐 역시나 css는 같이 딸려 온 것을 사용했더니 깔끔하고 좋습니다. js 파일들 경로를 못 찾아서 삽질을 했네요. 이젠 css랑 js파일 경로 지정해 주는 방법을 완벽히 파악했습니다.

사용하는 방법
1. 먼저 필요한 js 파일들을 다운로드 합니다.
2. js파일들을 head 태그 사이에서 경로를 지정해 줍니다.
3. input 태그에서 class와 name 속성을 잘 사용합니다.
4. validator를 사용하는 스크립트를 작성합니다.

1. 여기서 다운로드 할 수 있습니다.

2. js나 css파일들의 경로는 web폴더 기준입니다.
사용자 삽입 이미지
패키지 구조가 위와 같을 때 addMember.jsp에서 ../../../js/뭐시기.js 이런식으로 접근이 안되더군요.

web폴더를 기준으로 js/뭐시기.js 이렇게 써주면 됩니다. 따라서 다음과 같이 코딩하면 됩니다.
사용자 삽입 이미지

3. ID 필드 부분의 코드를 보시면 다음과 같습니다.
<div class="form-row">
      <div class="field-label"><label for="field1">ID</label>:</div>
      <div class="field-widget"><input name="member.id" id="field1" class="required" title="Enter your id" /></div>
</div>

div는 css를 먹이기 위해 사용했습니다. 빨간 부분이 핵심 부분인데요. 그 중에서도 id와 class 속성이 초 핵심 부분입니다.

id는 해당 컴포넌트를 지칭하기 위한 것입니다. 나중에 자바스크립트에서 저 이름을 사용합니다

class 속성에는 다음과 같은 값을 줄 수 있는데요. 저기에 적당한 값을 넣어 주면 그에 해당하는 validation을 해줍니다.
    * required (not blank)
    * validate-number (a valid number)
    * validate-digits (digits only)
    * validate-alpha (letters only)
    * validate-alphanum (only letters and numbers)
    * validate-date (a valid date value)
    * validate-email (a valid email address)
    * validate-url (a valid URL)
    * validate-date-au (a date formatted as; dd/mm/yyyy)
    * validate-currency-dollar (a valid dollar value)
    * validate-selection (first option e.g. 'Select one...' is not selected option)
    * validate-one-required (At least one textbox/radio element must be selected in a group - see below*)

4. validator 객체를 사용하는 스크립트를 작성합니다. 위 예제에 있던 스크립트를 그대로 사용했습니다.

<script type="text/javascript">
    function formCallback(result, form) {
        window.status = "valiation callback for form '" + form.id + "': result = " + result;
    }

    var valid = new Validation('test', {immediate : true, onFormValidate : formCallback});
    Validation.addAllThese([
        ['validate-password', 'Your password must be more than 6 characters and not be \'password\' or the same as your name', {
            minLength : 7,
            notOneOf : ['password','PASSWORD','1234567','0123456'],
            notEqualToField : 'field1'
        }],
        ['validate-password-confirm', 'Your confirmation password does not match your first password, please try again.', {
            equalToField : 'field8'
        }]
    ]);
</script>

대강 해석은 되고 내용 추가나 변경은 하겠는데 막상 이렇게 작성하라면 못하겠네요. 뭐 걍 당분간은 컨트롤 C + V 로~  :)

'모하니? > Coding' 카테고리의 다른 글

Spring 설정파일에서 'p' 네임스페이스 사용하기  (2) 2007.04.29
Eclipse에 Spring XML 기반 Configuration 탬플릿 등록  (0) 2007.04.29
태그파일 멋쟁이!  (2) 2007.04.23
문자열 생성기 prototype  (0) 2007.04.18
문자열 생성기  (0) 2007.04.18
Really easy field validation 사용하기  (4) 2007.04.18
Semina Helper v0.7  (2) 2007.04.13
Semina Helper v0.5  (0) 2007.04.06
아 이런 바보..ㅠ.ㅠ  (2) 2007.03.31
Report Validator v1.0  (0) 2007.03.29
JAR, WAR 에피소드 해결 방법  (0) 2007.03.29
top

  1. Favicon of http://seal.tistory.com BlogIcon 물개 2007.04.18 09:30 PERM. MOD/DEL REPLY

    흠.. 막강정리 로군요. 감사합니다. :)

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2007.04.18 13:54 PERM MOD/DEL

    흐흣 좋은 글 알려주셔서 감사합니다. 어제 validation에 관한 답변두요~ :)

  2. Favicon of http://chanwook.tistory.com BlogIcon 찬욱 2007.04.18 10:06 PERM. MOD/DEL REPLY

    좋아요~좋아~

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2007.04.18 13:54 PERM MOD/DEL

    ㅇㅇ이제 쪼금 볼만해ㅋㅋ

Write a comment.


Validator 사용하기



앞에서 만든 검색창을 사용할 때 빈 값을 넣으면 에러 메시지가 오른쪽에 출력하도록 하고 싶어졌습니다.

사용자 삽입 이미지

저렇게 해주고 싶으면 먼저 Validator가 필요하고...Controller에 Validator를 등록해줘야 하고...View에서 에러 출력할 부분을 표시해 줘야 합니다.

1. Validator 구현하기

public class SearchingValidator implements Validator {

    @SuppressWarnings("unchecked")
    public boolean supports(Class clazz) {
        return MemberCommand.class.isAssignableFrom(clazz);
    }

    public void validate(Object obj, Errors errors) {
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "keyword", "required", "Field is required.");
    }
}

위 코드는 Spring Reference 13.9.12에 있는 error tag 부분에 있는 소스를 거의 그대로 사용했습니다. 여기에 있는 코드를 보기 전에는 Pro Spring을 보고 아래처럼 구현했었습니다. 전 위가 더 간단해 보이고 편했습니다.
2. Controller에 등록하기.

    <bean name="/search.do"
        class="member.web.SearchMemberController">
        <property name="memberRepository" ref="memberRepository" />
        <property name="validator" ref="searchingValidator" />
    </bean>

    <!-- Validator 등록 -->
    <bean name="searchingValidator" class="validator.SearchingValidator"/>

3. View에 자리잡기.

        <table>
            <tr>
                <td>SEARCH:</td>
                <td><form:input path="keyword" /></td>
                <td><form:errors path="keyword" /></td>
                <td><input type="submit" value="GO" /></td>
            </tr>
        </table>

4. 실험해 봤습니다.
사용자 삽입 이미지

수고했삼~

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

DisplayTag 링크 기능  (0) 2007.02.08
Validator 사용하기  (0) 2007.02.07
검색창 하나로 모든 필드에서 검색하기.  (4) 2007.02.07
SimpleFormController 에피소드2  (0) 2007.02.02
SimpleFormController 에피소드1  (2) 2007.02.02
Spring's form tag  (0) 2007.02.01
DisplayTag과 SpringMVC  (0) 2007.01.31
DisplayTag 배끼기  (2) 2007.01.31
주소록 개발 카탈로그  (4) 2006.12.30
JSP 화면 작성  (0) 2006.12.29
Spring MVC configuration 파일들 설정 하기  (0) 2006.12.26
top

TAG validator

Write a comment.