Сопоставить строковые свойства с JSONB

#java #postgresql #hibernate #jpa

#java #postgresql #переход в спящий режим #jpa

Вопрос:

Я пытался сопоставить свои строковые свойства с JSONB Postgresql, используя JPA. Я много раз читал идеальную статью Влада Михальчи, а также видел относительные вопросы и проблемы с подобными материалами. НО у меня все еще есть это исключение org.postgresql.util.PSQLException: ERROR: column "json_property" is of type jsonb but expression is of type character varying каждый раз, когда я пытаюсь вставить что-то в свою таблицу.

И что еще хуже — все эти советы в подобных вопросах были полезны, пока я не изменил свой класс сущности и не сделал его наследующим суперкласс. И теперь ситуация такова:

  1. Если @TypeDef и @Type в моем дочернем классе, и это отлично работает
  2. Но я хочу использовать уровень абстракции и установить аннотации, которые я заметил выше, для моего базового класса сущностей, и после этого исключение говорит мне: «Привет! Это снова я ‘

Моя иерархия довольно проста, и вот она:

Базовая сущность

 @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@MappedSuperclass
public abstract class AbstractServiceEntity implements Serializable {

private Integer id;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}
  

Дочерняя сущность

 @Entity
@Table(schema = "ref", name = "test_json_3")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class TestJson extends AbstractServiceEntity {

@Type(type = "jsonb")
@Column(columnDefinition = "jsonb")
private String jsonProperty;
  

Моя таблица

 create table ref.test_json_3
(
id serial primary key,
json_property jsonb 
)
  

UPD
Я успешно вставил запись с помощью собственного запроса JPA, но мне пришлось развернуть свой запрос в запрос гибернации. Не уверен, что это самый удобный способ управлять вставкой данных в БД. Мой вопрос актуален, мне все еще нужна ваша помощь) Пример с собственным запросом ниже.

Фрагмент кода с результатом

 @Repository
public class JpaTestRepository {

@PersistenceContext
private EntityManager entityManager;

@Transactional
public void insert(TestJson testJson) {
    entityManager.createNativeQuery("INSERT INTO test_json_3 (json_property) VALUES (?)")
            .unwrap(Query.class)
            .setParameter(1, testJson.getJsonProperty(), JsonBinaryType.INSTANCE)
            .executeUpdate();
}
  

Ответ №1:

Наконец-то я нашел решение своей проблемы. Ответ таков — просто используйте ваши @Column(columnDefinition = "jsonb") и @Type(type = "jsonb" через геттеры, но не свойства класса.

определение сущности

 @Entity
@Table(schema = "ref", name = "test_json_3")
@NoArgsConstructor
@AllArgsConstructor
@Setter
public class TestJson extends AbstractServiceEntity {

private String jsonProperty;

@Type(type = "jsonb")
@Column(columnDefinition = "jsonb")
public String getJsonProperty() {
    return jsonProperty;
}
  
  

Ответ №2:

Альтернативное решение для сопоставления строки с типом Jsonb. Просто добавьте следующую аннотацию к вашей строке.

 @ColumnTransformer(write = "?::jsonb")
private String jsonProperty;
  

Ответ №3:

Вы можете попробовать добавить @TypeDefs в класс TestJson:

 @TypeDefs({
        @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
})
public class TestJson extends AbstractServiceEntity {
  

Комментарии:

1. typedef теперь устарел