JPA Annotation for the PostgreSQL TEXT Type – 用于PostgreSQL TEXT类型的JPA注解

最后修改: 2019年 10月 23日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

In this quick tutorial, we’ll explain how to manage the PostgreSQL TEXT type using the annotations defined by the JPA specification.

在这个快速教程中,我们将解释如何使用JPA规范所定义的注释来管理PostgreSQL TEXT类型

2. The TEXT Type in PostgreSQL

2.PostgreSQL中的TEXT类型

When working with PostgresSQL we may, periodically, need to store a string with an arbitrary length.

在使用PostgresSQL时,我们可能定期需要存储一个任意长度的字符串。

For this, PostgreSQL provides three character types:

为此,PostgreSQL提供了三种字符类型。

  • CHAR(n)
  • VARCHAR(n)
  • TEXT

Unfortunately, the TEXT type is not part of the types that are managed by the SQL standard. This means that if we want to use JPA annotations in our persistence entities, we may have a problem.

不幸的是,TEXT类型不属于SQL标准所管理的类型。这意味着如果我们想在持久化实体中使用JPA注释,我们可能会遇到问题

This is because the JPA specification makes use of the SQL standard. Consequently, it doesn’t define a simple way to handle this type of object using, for example, a @Text annotation.

这是因为JPA规范使用的是SQL标准。因此,它没有定义一个简单的方法来处理这种类型的对象,例如,使用@Text注释。

Luckily, we have a couple of possibilities for managing the TEXT data type for a PostgreSQL database:

幸运的是,我们有几种可能性来管理PostgreSQL数据库的TEXT数据类型。

  • We can use the @Lob annotation
  • Alternatively, we can also use the @Column annotation, combined with the columnDefinition attribute

Let’s now take a look at the two solutions beginning with the @Lob annotation.

现在让我们来看看从@Lob注解开始的两个解决方案。

3. @Lob

3.@Lob

As the name suggests, a lob is a large object. In database terms, lob columns are used to store very long texts or binary files.

顾名思义,lob是一个lob对象。在数据库方面,lob列用于存储很长的文本或二进制文件

We can choose from two kinds of lobs:

我们可以从两种滚球中进行选择。

  • CLOB – a character lob used to store texts
  • BLOB – a binary lob that can be used to store binary data

We can use the JPA @Lob annotation to map large fields to large database object types.

我们可以使用JPA的@Lob注解来将大型字段映射到大型数据库对象类型。

When we use the @Lob record on a String type attribute, the JPA specification says that the persistence provider should use a large character type object to store the value of the attribute. Consequently, PostgreSQL can translate a character lob into a TEXT type.

当我们在一个String类型的属性上使用@Lob记录时,JPA规范说持久化提供者应该使用一个大的字符类型对象来存储该属性的值。因此,PostgreSQL可以将一个字符lob翻译成一个TEXT类型。

Let’s suppose we have a simple Exam entity object, with a description field, which could have an arbitrary length:

假设我们有一个简单的Exam实体对象,有一个description字段,它可以有一个任意的长度。

@Entity
public class Exam {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @Lob
    private String description;
}

Using the @Lob annotation on the description field, we instruct Hibernate to manage this field using the PostgreSQL TEXT type.

使用描述字段上的@Lob注解,我们指示Hibernate使用PostgreSQL TEXT类型来管理这个字段。

4. @Column

4.@柱

Another option for managing the TEXT type is to use the @Column annotation, together with the columnDefinition property.

管理TEXT类型的另一个选择是使用@Column注解,以及columnDefinition属性。

Let’s use the same Exam entity object again but this time we’ll add a TEXT field, which could be of an arbitrary length:

让我们再次使用同一个Exam实体对象,但这次我们将添加一个TEXT字段,它的长度可以是任意的。

@Entity
public class Exam {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;
    
    @Lob
    private String description;
    
    @Column(columnDefinition="TEXT")
    private String text;

}

In this example, we use the annotation @Column(columnDefinition=”TEXT”). Using the columnDefinition attribute allows us to specify the SQL fragment which will be used when constructing the data column for this type.

在这个例子中,我们使用注解@Column(columnDefinition=”TEXT”)。使用columnDefinition属性允许我们指定在为该类型构建数据列时将使用的SQL片段。

5. Bringing It All Together

5.把所有的东西集中起来

In this section, we’ll write a simple unit test to verify our solution is working:

在这一节中,我们将写一个简单的单元测试来验证我们的解决方案是否有效。

@Test
public void givenExam_whenSaveExam_thenReturnExpectedExam() {
    Exam exam = new Exam();
    exam.setDescription("This is a description. Sometimes the description can be very very long! ");
    exam.setText("This is a text. Sometimes the text can be very very long!");

    exam = examRepository.save(exam);

    assertEquals(examRepository.find(exam.getId()), exam);
}

In this example, we begin by creating a new Exam object and persisting it to our database.  We then retrieve the Exam object from the database and compare the result with the original exam we created.

在这个例子中,我们首先创建一个新的Exam对象并将其持久化到数据库中。 然后我们从数据库中检索Exam对象,并将其结果与我们创建的原始考试进行比较。

To demonstrate the point, if we quickly modify the description field on our Exam entity:

为了证明这一点,如果我们快速修改我们的Exam实体上的描述字段。

@Column(length = 20)
private String description;

When we run our test again we’ll see an error:

当我们再次运行我们的测试时,我们会看到一个错误。

ERROR o.h.e.jdbc.spi.SqlExceptionHelper - Value too long for column "TEXT VARCHAR(20)"

6. Conclusion

6.结语

In this tutorial, we covered two approaches for using JPA annotations with the PostgreSQL TEXT type.

在本教程中,我们介绍了两种在PostgreSQL TEXT类型中使用JPA注释的方法。

We began by explaining what the TEXT type is used for and then we saw how we can use the JPA annotations @Lob and @Column to save String objects using the TEXT type defined by PostgreSQL.

我们首先解释了TEXT类型的用途,然后我们看到了如何使用JPA注解@Lob@Column 来使用PostgreSQL定义的TEXT类型保存String对象。

As always, the full source code of the article is available over on GitHub.

一如既往,文章的完整源代码可在GitHub上获得。