2013-01-24 2 views
10
우리는이 (그루비 코드)처럼 보이는 JPA 주석 유형을 사용하고

:PostgreSQL 문자열을 텍스트 유형으로 마이그레이션하는 방법은 무엇입니까?

가 처음 내가 JPA에 아주 새로운이고 SQL 먼저, 다음 주석 클래스가 일치했다 썼다 작성되었습니다
@Entity 
@EqualsAndHashCode 
class TextNote extends Serializable { 
    @Id Long id 
    String text 
} 

SQL. 다음은 내가 원하는 테이블처럼 PostgreSQL을에 최대 읽기는 듯 :이 일을

CREATE TABLE textnote (
    id bigint NOT NULL, 
    text text 
); 

, 우리는이처럼 보였다 테이블을했다 :

id |   text 
-----+------------------------ 
837 | really long text here 

는 내가 지금하고 싶은 것은 정확 JPA 엔티티는 다음과 같이합니다 :

@Entity 
@EqualsAndHashCode 
class TextNote extends Serializable { 
    @Id Long id 
    @Lob String text 
} 

@Lob 주석에게 JPA 공급자를 추가 (내 경우, 최대 절전 모드)의 경우에 나를 위해 올바르게 DDL을 생성 할 수 우리는 데이터베이스를 교환하려고합니다. 또한 텍스트 필드를 원하는대로 정확하게 문서화합니다. 나는 그것은 정말 긴 텍스트를 반환) 문자열 gettext에를 (사용하여 코드를 읽을 때와 같이 새로운 메모 괜찮

id |   text 
-----+------------------------ 
837 | 33427 

: 이제 메모가 작성되는 때 나는 이런 식으로 뭔가를 참조하십시오. 솔직히 PostgreSQL이 text 유형을 구현하는 방법을 모르거나 이론적으로해야 할 필요는 없습니다. 그러나 우리의 프로덕션 데이터베이스에는 이미 @Lob 주석이없는 이전 코드를 사용하여 많은 노트가 저장되어 있습니다. 기존 데이터베이스에 새 코드를 실행하면 다음과 같은 문제가 발생하는 경우 기존 노트

org.springframework.dao.DataIntegrityViolationException: Bad value for type long : not a number this time; SQL [n/a]; nested exception is org.hibernate.exception.DataException: Bad value for type long : not a number this time 

제대로 @Lobtext 유형을 사용하는 기존의 노트를 마이그레이션 할 SQL의 방법이? 미리 감사드립니다.

답변

12

Postgres large object docs을 기반으로하면 각 텍스트 청크를 파일에 작성하고 개별적으로 가져와야 할 것처럼 보입니다. SQL에서해야 할 일이 아닙니다.

JPA에 대해서는 잘 모르겠지만 @Lob은 DDL 또는 데이터베이스 스위칭과 관련이 있습니까? 열의 유형을 완전히 변경했습니다. Postgres의 text 유형에 무슨 문제가 있었습니까? 다른 곳에서 데이터를 저장하는 기본 포스트 그레스 "대형 개체"로

진짜 문제는 @Lob이 포스트 그레스 text 열을 생성하는,하지만 Hibernate treats it : 여기에 루프를 닫으면


그래서이 의견에 손실되지 않습니다 테이블에 oid 만 남겨둔다 (컬럼 타입에 따라 텍스트로 저장된다). 이것은 보통 텍스트에 대해 원하는 것이 아닙니다.

OP의 해결책은 Hibernate가 일반 텍스트를 저장하도록 강제하기 위해 @Type(type="org.hibernate.type.StringClobType")을 때 리려고했다.

Postgres는 일반적으로 텍스트를 5 자리 정수로 저장하지 않습니다. :)

+0

에서 큰 도움을 얻었다는 JPA 제공자는 내가 원하는하지 않은, 열 유형 VARCHAR있는 테이블을 생성합니다. '@ Lob'은 PostgreSQL'text' 타입을 생성합니다. 이것은 정확히 원하는 것입니다. 데이터베이스를 전환하려면 JPA 공급자를 사용하여 DDL을 생성해야합니다. '@ Lob '은 그렇게하기 위해 필요합니다. 이해가 되니? – Joe

+0

'@ Lob'이'텍스트 '를 생성하고 있습니까? 문서와 게시 된 출력 모두'oid'를 생성 할 것이라고 생각합니다. Postgres가 큰 객체를 저장하는 방법입니다. 그것이 진정으로'text'라면, 단지 미스터리가 아닌 _text_를 볼 수 있습니다. – Eevee

+0

나는'@ Lob' 어노테이션으로 출력 한 테이블을 다음과 같이 긍정적이다. [gist] (https://gist.github.com/4630173) – Joe

7

JPA를 사용하여 내 엔티티에 주석을 달고 최대 절전 모드로 유지합니다. 하지만 최대 절전 모드의 특정 주석을 내 개체에 추가하고 싶지 않습니다. 따라서 엔터티 + 주석을 포함하는 데이터 병이 있습니다. 그런 다음 내 구현에서 persistence.xml을 지정하고 'CustomTypes.hbm.xml'을 추가합니다.자동 스캔되거나 persistence.xml의 mapping-file 태그를 통해 추가됩니다.

이 매핑에는 basictyperegistry에서 재정의하려는 유형이 포함되어 있습니다. 이 경우 materialized_clob 유형이 사용됩니다. 쿼리 도구로 데이터베이스를 탐색 할 때 실제 내용을 직접 볼 수 있기를 바랍니다. 그래서 나는 추가 :

<typedef name="materialized_clob" class="org.hibernate.type.TextType" /> 

내 데이터 패키지의 특정 주석을 추가 할 필요없이 모든 CLOB에 대해 지정된 유형의 사용을 강제로.

DEBUG 레벨에서 org.hibernate.type.BasicTypeRegistry를 로깅하여 매핑을 검토 할 수 있습니다.

이 문제를 파악하는 데 시간이 걸렸으며 동일한 문제를 겪고있는 사람에게 도움이되기를 바랍니다. 아마 이것도 당신의 문제를 해결할 것이기 때문에 여기에 게시할만한 가치가 있다고 생각했습니다.

0

봄을 사용하는 경우 최대 절전 모드 형식을 삽입하려면 LocalSessionFactoryBean 자손을 만들 수 있습니다. 예 참조 :

public class CustomSessionFactoryBean extends LocalSessionFactoryBean { 

    @Override 
    protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) { 
     // To store @Lob annotated Strings in TEXT fields. 
     // By default for Postgres generated TEXT column, but stored OID of Postgres LOB object 
     sfb.registerTypeOverride(new TextType() { 
      @Override 
      public String getName() { 
       return StandardBasicTypes.MATERIALIZED_CLOB.getName(); 
      } 
     }); 
     sfb.registerTypeOverride(new NTextType() { 
      @Override 
      public String getName() { 
       return StandardBasicTypes.MATERIALIZED_NCLOB.getName(); 
      } 
     }); 

     super.buildSessionFactory(sfb); 
    } 
} 

당신은 최대 절전 모드 특정 주석 @Type를 사용할 필요가 없습니다, 그냥 내가 그 말 확신하지만, 사람을 위해 미래에 같은 문제가 CustomSessionFactoryBean

1

@Lob와 문자열 속성을 주석 및 사용 .

또한 OID가 아닌 열의 텍스트 열에 이전 데이터가 직접있는 비슷한 문제가 발생했습니다. 내가 업그레이드 된 응용 프로그램과 데이터를 사용하려고 할 때 그리고 나도 내가 this script를 만들어이 문제를 해결하려면

Bad value for type long 

을 얻고 있었다. 앞으로 누군가를 도울 수 있습니다.

내가 그 주석없이이 게시물 here

관련 문제