Writing to JSON column of Postgres database using Spring/JPA

dru*_*ist 15 spring json jpa postgresql-9.3

我有一个名为"test"的表,其中包含Postgres 9.3中json类型的列"sample_column".我正在尝试使用Spring/JPA将以下内容写入列:{"name":"Updated name"}

我在其他帖子上读到我需要添加一个自定义转换器来将字符串映射到json类型.这是我现在的代码:

TestDAO.java:

@Entity
@Table(name="test")
public class TestDAO implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id", unique=true, nullable=false)
    private Long id;   

    @Column(name="sample_column")
    @Convert(converter = MyCustomConverter.class)
    private MyCustomClass sampleColumn;

    // Getter / Setters
}
Run Code Online (Sandbox Code Playgroud)

用于映射json内容的CustomClass:

public class MyCustomClass {
    @JsonProperty("name")
    public String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}
Run Code Online (Sandbox Code Playgroud)

最后,转换器类:

@javax.persistence.Converter
public class MyCustomConverter implements AttributeConverter<MyCustomClass, String> {

    private final static ObjectMapper objectMapper = new ObjectMapper();

    @Override
    @NotNull
    public String convertToDatabaseColumn(@NotNull MyCustomClass myCustomObject) {
        try {
            return objectMapper.writeValueAsString(myCustomObject);
        } catch (Exception ex) {
            return null;
        }
    }

    @Override
    @NotNull
    public MyCustomClass convertToEntityAttribute(@NotNull String databaseDataAsJSONString) {
        try {
            return objectMapper.readValue(databaseDataAsJSONString, MyCustomClass.class);
        } catch (Exception ex) {
            return null;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我正在尝试按如下方式设置json列:

testDAO.getSampleColumn().setName("Updated name");
testRepository.saveAndFlush(testDAO);
Run Code Online (Sandbox Code Playgroud)

但是当我尝试保存它时,我收到以下错误:

Caused by: org.postgresql.util.PSQLException: ERROR: column "sample_column" is of type json but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
Run Code Online (Sandbox Code Playgroud)

但是,我能够使用testDAO.getSampleColumn().getName(); 这里的问题读取JSON列吗?我不想在表中添加任何强制转换,以便自动将Varying转换为Json.

谢谢.

Cra*_*ger 14

您需要setObject在JDBC级别使用,或者传递PgJDBC参数stringtype=unspecified以允许从字符串类型隐式转换为json等.

这是PostgreSQL对类型转换过于严格的问题.

  • 好吧,看起来像Spring-boot提供了一个`spring.datasource.connection-properties`,我们可以使用它来添加任何其他参数.谢谢. (9认同)
  • 我正在使用Spring-boot,我在application.properties文件中设置了所有数据库属性.是否有一个特定的属性我可以用来设置`stringtype = unspecified`?现在,我只是将它作为一个参数添加到`spring.datasource.url`(即)`spring.datasource.url = jdbc:postgresql:// localhost:5432/dbname?stringtype = unspecified`.这样做有效.但我不想将其添加到数据源URL.我更愿意,如果它是一个单独的财产. (5认同)
  • 非常好的答案,特别是与评论一起.我希望看到答案扩展到评论中的信息. (4认同)
  • `spring.datasource.connection-properties` [不再有效](http://stackoverflow.com/questions/40250678/set-jpa-utf-8-encoding-in-application-properties/40255073#comment67774997_40255073)。这个对我有用:`spring.datasource.tomcat.connection-properties` (2认同)

abb*_*bas 13

对于使用 Spring-boot 的人来说,有两种方法可以做到 @Craig Ringer 所说的

spring.datasource.url=jdbc:postgresql://localhost:5432/postgres?stringtype=unspecified
Run Code Online (Sandbox Code Playgroud)

或使用属性

spring.datasource.hikari.data-source-properties.stringtype=unspecified
Run Code Online (Sandbox Code Playgroud)