首页 > 解决方案 > JPA/Hibernate:保存一个包含实体列表的实体,这些实体在对象层次结构中保存一个二维对象数组

问题描述

我试图坚持我的游戏类,结构如下:

我想要的是游戏和棋盘实体之间的一对多关系,以及作为嵌入式属性的棋盘类中的字段。为了嵌入它,我想编写自己的映射代码,将二维数组转换为代表字段的符号字符串,但如果这不可能,那么我将使用单表策略保存层次结构。

我仍在学习 JPA/Hibernate,所以我一次要做的事情太多了,无法完全掌握如何解决这个问题。

这是我尝试过的:

为 Board 实现 AttributeConverter

我了解到这是不可能的,因为 AttributeConverters 不能用于关系属性(JPA 规范)。

为 Field[][] 实现 AttributeConverter,并使其成为嵌入式属性

@Entity
@NoArgsConstructor
public class Game {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Getter
    private Long id;

    @OneToMany(mappedBy = "game", cascade = CascadeType.ALL)
    @Getter
    private List<Board> boards = new ArrayList<>();
...
}
@Entity
public class Board {

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

    @ManyToOne()
    @JoinColumn(name="game_id")
    private Game game;

    @Embedded
    @Convert(converter = FieldsConverter.class, attributeName = "field")
    private Field[][] fields;

与 FieldsConverter 是

@Converter
public class FieldsConverter implements AttributeConverter<Field[][], String> {

IntelliJ 已经给出了“嵌入式属性类型不应该是 Field[][]”错误,运行会导致奇怪的 ArrayIndexOutOfBoundsException(请参阅https://pastebin.com/ZVbCGaGA以获取完整的堆栈跟踪)。

自己编写 JDBC 映射

我也开始自己编写一个 BoardRepository,在其中我手动完成了 Fields 属性的映射,但后来我记得那时我可能没有 Game 和 Board 之间的托管关系,或者 JPA 将提供的延迟加载,所以我在我完全准备好之前停了下来。

我读到的接近解决方案的一件事是:https ://vladmihalcea.com/multidimensional-array-jpa-hibernate/ ,但我不确定如何将其调整为嵌入属性和对象实际上是一部分对象层次结构。

谁能给我一些关于如何进行的指示?

标签: javaarrayshibernatejpa

解决方案


推荐阅读