JPA 및 PostgreSQL 텍스트
13281 단어 yugabytedbpostgresjpahibernate
끈
JPA 주석 없이
String
를 선언합니다.public class UnlimitedText {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)
private Long id;
private String name;
재현하려는 경우 전체 프로그램은 다음과 같습니다.
https://gist.github.com/FranckPachot/fcd11b5a63b7512cfe3404ed61a3fa53
이것은
hbm2ddl
로 다음을 생성합니다. create table unlimited_text (
id int8 not null,
name varchar(255),
primary key (id)
)
255자... 너무 크거나 작습니다. 아마도 당신이 원하는 것이 아닐 것입니다.
@컬럼(길이=)
길이를 지정할 수 있습니다.
@Column(length=10485760)
private String name;
생성된 DDL:
create table unlimited_text (
id int8 not null,
name varchar(10485760),
primary key (id)
)
좋습니다. 일부 데이터베이스에는 적합하지만 PostgreSQL에는 크기에 대해 생각할 필요가 없는
text
데이터 유형이 있습니다. 나는 이것을 선호한다. YugabyteDB는 블록 제한 없이 문서로 저장하므로 크기를 제한하지 않으려면 크기를 지정할 필요가 없습니다.@Type(type="org.hibernate.type.StringType")
StringType을 표시하는 것은 올바른 방법이 아닙니다. 기본값과 같이
varchar(255)
생성됩니다. @Type(type="org.hibernate.type.StringType")
private String name;
생성된 DDL:
create table unlimited_text (
id int8 not null,
name varchar(255),
primary key (id)
)
@Type(type="org.hibernate.type.TextType")
text
에 대한 올바른 Hibernate 유형은 TextType
입니다. @Type(type="org.hibernate.type.TextType")
private String name;
생성된 DDL:
create table unlimited_text (
id int8 not null,
name text,
primary key (id)
)
엄청난. 이것이 내가 원하는거야.
@열(열 정의="텍스트")
어떤 이유로든 PostgreSQL 데이터 유형 이름을 언급하는 것을 선호하는 경우 다음과 같이 작동합니다.
@Column(columnDefinition="text")
private String name;
생성된 DDL:
create table unlimited_text (
id int8 not null,
name text,
primary key (id)
)
이제 텍스트는 PostgreSQL 또는 YugabyteDB에서 제한이 있습니다.
예시:
yugabyte=# create table demo as select lpad('x',269000000,'x');
DROP TABLE
ERROR: invalid memory alloc request size 1076000004
yugabyte=# create table demo as select lpad('x',900000000,'x');
ERROR: requested length too large
더 큰 개체를 원할 때 PosttgreSQL은 큰 개체(LOB)를 일부 지원합니다.
@Lob
private String name;
생성된 DDL:
create table unlimited_text (
id int8 not null,
name text,
primary key (id)
)
좋아 보이지만
Hello World
를 삽입하고 무엇이 있는지 살펴보겠습니다.select * from unlimited_text
id | name
----+-------
1 | 16592
(1 row)
텍스트 필드의 OID입니다. 이것은 최대 절전 모드 버그입니다. PostgreSQL에서는 LOB를 잘못된 위치에 저장하고 OID 식별자를 저장하는 것이 올바르지만 이것은
text
데이터 유형 열이 아니어야 합니다.Heover, 큰 개체 함수는 이것을
oid
로 변환하면 작동합니다.postgres=# select * from pg_largeobject;
loid | pageno | data
-------+--------+--------------------------
16533 | 0 | \x48656c6c6f20576f726c64
16542 | 0 | \x48656c6c6f20576f726c64
16592 | 0 | \x48656c6c6f20576f726c64
(3 rows)
postgres=# select *,lo_get(name::oid),convert_from(lo_get(name::oid),'UTF8') from unlimited_text;
id | name | lo_get | convert_from
----+-------+--------------------------+--------------
1 | 16592 | \x48656c6c6f20576f726c64 | Hello World
(1 row)
@Column(columnDefinition="oid")
다음은
oid
데이터 유형을 지정하는 해결 방법입니다. @Column(columnDefinition="oid")
@Lob
생성된 DDL:
create table unlimited_text (
id int8 not null,
name oid,
primary key (id)
)
이것은 PostgreSQL에서 올바르게 작동하지만 YugabyteDB는 대형 개체를 지원하지 않습니다. 당신은 만날 것입니다:
Jul 07, 2022 3:52:20 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: ERROR: Illegal state: Transaction for catalog table write operation 'pg_largeobject_metadata' not found
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not insert: [PostgresText$UnlimitedText]
Caused by: org.hibernate.exception.GenericJDBCException: could not insert: [PostgresText$UnlimitedText]
Caused by: org.postgresql.util.PSQLException: ERROR: Illegal state: Transaction for catalog table write operation 'pg_largeobject_metadata' not found
필요하신 분들은 팔로우#3576 부탁드립니다. 그러나 클라우드 네이티브 환경에서는 해당 객체가 URL만 있는 데이터베이스가 아니라 AWS의 Amazon S3와 같은 객체 스토리지에 저장될 가능성이 높습니다.
Reference
이 문제에 관하여(JPA 및 PostgreSQL 텍스트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/yugabyte/jpa-and-postgresql-text-2ma6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)