Hibernate/JPA сопоставляет столбцы с типом карты

Spring Boot, Hibernate/JPA и MySQL здесь. У меня есть следующая таблица:

CREATE TABLE IF NOT EXISTS fizzbuzzes (
    fizzbuzz_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    fizzbuzz_type_a VARCHAR(250) NOT NULL,
    fizzbuzz_type_b VARCHAR(250) NOT NULL,
    fizzbuzz_type_c VARCHAR(250) NOT NULL,
    fizzbuzz_type_d VARCHAR(250) NOT NULL,
    fizzbuzz_type_e VARCHAR(250) NOT NULL,
    fizzbuzz_type_f VARCHAR(250) NOT NULL,
    fizzbuzz_type_g VARCHAR(250) NOT NULL,
    fizzbuzz_type_h VARCHAR(250) NOT NULL,
    fizzbuzz_type_i VARCHAR(250) NOT NULL,
    fizzbuzz_type_j VARCHAR(250) NOT NULL,
    fizzbuzz_type_k VARCHAR(250) NOT NULL,
    fizzbuzz_type_l VARCHAR(250) NOT NULL,
    fizzbuzz_type_m VARCHAR(250) NOT NULL,
    fizzbuzz_type_n VARCHAR(250) NOT NULL,
    fizzbuzz_type_o VARCHAR(250) NOT NULL,
    fizzbuzz_type_p VARCHAR(250) NOT NULL,

    CONSTRAINT pk_fizzbuzzes PRIMARY KEY (fizzbuzz_id);
);

Я хотел бы, чтобы эта таблица отображалась в O/R для объекта JPA, который имеет Map<String,String> удерживая все типы fizzbuzz от A до P.

Поэтому вместо того, что вы обычно видите:

@Entity
@Table(name = "fizzbuzzes")
public class Fizzbuzz {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "fizzbuzz_type_a")
    private String typeA;

    @Column(name = "fizzbuzz_type_a")
    private String typeB;

    // ...

    @Column(name = "fizzbuzz_type_a")
    private String typeP;

    // Getters, setters & ctors
}

... вместо этого я хотел бы:

@Entity
@Table(name = "fizzbuzzes")
public class Fizzbuzz {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "???")
    private Map<String,String> types;

    // Getters, setters & ctors
}

Где ключи types могут быть жестко закодированные строки typeA, typeB,..., typeP и значения types будут значения из соответствующих столбцов в таблице БД.

Можно ли это сделать, и если да, то как?

1 ответ

Решение

Вроде, как бы, что-то вроде. Это возможно, если вы согласны с наличием значений типов в отдельной таблице. Тогда вы можете использовать @ElmentCollection а также @MapKeyColumn,

Так, например:

@ElementCollection
@MapKeyColumn(name="type_key")
@Column(name="type_value")
@CollectionTable(name="fizzbuzz_types", joinColumns=@JoinColumn(name="fizzbuzz_id"))
Map<String, String> types= new HashMap<>(); 

В противном случае вам нужно жестко закодировать столбцы типа, как в первом примере, и вы можете добавить @PostLoad а также @PrePersist перехватывает для преобразования статических столбцов в / из переходной карты.

Что-то вроде:

@Entity

@Table (name = "fizzbuzzes") открытый класс Fizzbuzz { @Id @GeneratedValue(Strategy = GenerationType.IDENTITY) private Длинный идентификатор;

@Column(name = "fizzbuzz_type_a")
private String typeA;

@Column(name = "fizzbuzz_type_a")
private String typeB;

@Transient
private Map<String, String> types = new HashMap<>();

@PostLoad
public void toMap() {
   this.types.put("typeA", this.typeA);
   this.types.put("typeB", this.typeB);
}
@PrePersist
public void fromMap() {
   this.typeA = this.types.get("typeA");
   this.typeB= this.types.get("typeB");
}
Другие вопросы по тегам