2009-03-06 4 views
3

Oracle 10g 및 Hibernate 2.1 (이전 버전이지만 수정을 위해 업그레이드 할 수 없음)을 사용하고 있습니다. TIN, varchar2 (9)라는 nullable이 아닌 열이있는 테이블이 있습니다. 이 열은 플랫 파일에서로드 된 데이터를 스테이지하는 데 사용되므로 입력 파일에 9 개의 공백이 있으면 9 개의 공백 (즉, '')을 포함하여 길이가 9 인 문자열을 저장할 수 있습니다.Hibernate가 문자열을 자르는 것을 어떻게 막을 까?

  1. 오라클 10g는 자동으로 NULL로 빈 문자열로 변환 :

    는 내가 눈치 챘을하는 것입니다. 따라서 실행하면 :

    SELECT NVL('', 'Input string converted to NULL') FROM dual; 
    

    결과가 '입력 문자열을 NULL로 변환했습니다'가 아닌 ' 나는 이것이 문제와 관련이 있다고 생각한다.

  2. 하이버 네이트는 TIN 값이 다른 문자가없는 9 개 공백 (또는 임의의 개수의 공백) 인 레코드를 읽을 때 메모리에 값을 ''로 저장합니다. Hibernate는 값을 9 개의 공백에서 빈 문자열로 변경했다는 것을 생각해 내기 위해 속일 것입니다. 그런 다음 레코드가 데이터베이스에 다시 기록되면 Hibernate는 9 개의 공백 대신 빈 문자열을 쓰려고 시도하고 오라클은이를 분명히 null로 변환 한 다음 비공유 제약 조건 위반을 던집니다. 참고로

, 여기에 HBM은이 열의입니다 :

<property 
    name="tin" 
    type="java.lang.String" 
    column="TIN" 
    not-null="true" 
    length="9"> 

내 질문은, 어떻게 난 단지 문자열을 비울 공백이 포함 된 값을 변환하지 최대 절전 모드 지시 하는가?

업데이트 1 : 방금 'text'와 같은 문자열을 테스트 한 결과, Hibernate는 'text'라는 문자열을 만들고이 값이 변경되었다고 생각하면서 속이 빈 공간을 잘라내는 것을 발견했습니다. 나는 뭔가를 놓치고 있어야합니다. 이것은 기본 동작처럼 보이지 않습니다.

업데이트 2 : HBM을 Java 소스로 변환하는 hbm2java Ant 태스크가 String trims의 소스 일 수 있습니다. 아직도 조사 중이 야.

감사합니다, 제프

편집 : 변경된 질문의 표현이 더 정확합니다.

답변

3

최대 절전 모드 문제가 아니라는 것이 판명되었습니다. 작업하고있는 프로젝트는 hbm2java Ant 태스크를 사용하여 HBM 파일에서 Java POJO를 생성하도록 설정되었습니다. 이것은 setter의 모든 java.lang.String 속성을 다듬기 위해 작성된 getters/setters/equals/toString/etc의 소스 템플릿을 참조합니다. 문제를 해결하기 위해 문제가있는 클래스 하나를 비활성화하여 각 빌드에서 더 이상 생성되지 않도록 한 다음 TIN 속성에서 트림을 제거했습니다.

2

최대 절전 모드에 대해 모르겠다. 그러나 오라클은 빈 문자열을 Null 값으로 처리한다는 것을 알고 있습니다. 그리고 그것에 대한 해결 방법은 없습니다.

4

이 문제를 처리하는 한 가지 방법은 입니다. hibernate.org의 링크에는 String escaping을 위해 이미 만들어진 클래스가있다. 나는 이것이 '9 개의 공백을 빈 문자열로 변환하지 말도록 최대 절전 모드로 전환하는 법'을 직접적으로 대답하지 않지만 데이터베이스 측의 저장 문제를 해결할 것이라고 생각합니다.

해당 페이지에는 두 개의 구현이 있습니다. 하나는 모든 문자열을 이스케이프 처리하고 (원하는 방식으로 9 개의 공백 문자를 처리 할 수 ​​있음), ''값만 이스케이프 처리하는 것입니다. 전자가 당신에게 더 잘 어울리는 것 같습니다.

기록을 위해 - 나는이 방법을 직접 사용하고 있습니다. 클래스 경로에 클래스를 추가하고 HBM.xml의 'type'속성을 정규화 된 클래스 이름 (예 : 속성 요소에 type = "my.fully.qualified.HibernateUserType"을 추가)로 설정하면됩니다.

자바 측에서는 클래스가 여전히 java.lang.String 및 사용자가 볼 것으로 예상되는 값을 처리하지만 최대 절전 모드에서는 UserType 클래스를 사용합니다.

+0

감사합니다. Joshua. 이것은 꽤 좋은 접근법처럼 보인다. 내가 보는 가장 큰 문제는 Hibernate 외부의 데이터에 접근하는 모든 것들은 그 값들이 이스케이프된다는 것을 알아야한다는 것이다. 하이버 네이트 트리밍 값의이 동작이 정상적인지/문서화되어 있는지 궁금합니다. – jlpp

+0

True - 최대 절전 모드 외부에서 데이터베이스에 액세스하는 다른 코드 부분이 있으면 문제가됩니다. –

+0

불행히도,이 경우입니다. 동일한 열을 읽고 쓰는 플랫 파일을 일괄 처리하기 위해 작성된 저장 프로 시저가 있습니다. 그래도 고마워. 너의 대답은 확고했다. – jlpp

관련 문제