gpt4 book ai didi

hibernate - 之后添加 JPA @OrderColumn 会导致集合错误的空索引列

转载 作者:行者123 更新时间:2023-12-01 14:15:10 39 4
gpt4 key购买 nike

假设我们有实体 A 和 B 的 @OneToMany 关系。每个 A 可以有多个 B。

@Entity
public class A{
@Id
private long id;
...
@OneToMany(mappedBy="ref")
private List<B> items;
...
}

@Entity
public class B{
@Id
private long id;

@ManyToOne
@JoinColumn(name = "A_ID")
private A ref;
}

此应用程序已投入生产一段时间,直到现在,保存到 db 中的 B 的顺序并不相关。

但是,现在需要 B 的确切顺序。为此,我添加了如下所示的 @OrderColumn。
@OneToMany
@OrderColumn(name="B_ORDER")
private List<B> items;

它工作正常,B 表现在具有带有订单值的 B_ORDER 列。

现在需要更新生产数据库。新列 B_ORDER 已添加到表 B。但是,对于现有行,此列没有值 (null)。当您尝试检索现有记录的 B 列表时,出现以下异常:
org.hibernate.HibernateException: null index column for collection

对于旧记录,可以按任何顺序列出 B 列表。 @OrderColumn 具有属性“nullable”,默认情况下为 true。但它没有帮助。

有没有一种 JPA 方法,还是我必须自己在 db 中填充那些空值?

在 Hibernate 4.3.7 中使用 JPA 2.1。

最佳答案

您遇到的问题是 JPA 提供程序(在您的情况下为 Hibernate)需要对 order 列的值进行连续(非稀疏)排序。

但是,当您向新数据库添加新列时,值将为 除非您定义了默认值 0。

您可能认为添加默认值就可以解决问题。抱歉,事实并非如此。如果您这样做,您的收藏将始终最多显示一件。

为了解决这个问题,你必须为每个集合添加一个连续的、非稀疏的编号。

在实践中,您应该临时更改您的实体,以便您可以实际访问相应的字段:

@Entity  
public class B{
@Id
private long id;

@ManyToOne
@JoinColumn(name = "A_ID")
private A ref;

@Column(name = "B_ORDER")
private Integer order;
}

现在您可以加载所有项目。接下来您需要做的是编写一个时态方法,该方法从数据库中加载所有项目,并为每个集合的每个项目编号,从 0 到集合的长度减 1。

以上建议只是我觉得方便的一种方式。有很多方法可以解决。如果你有足够的时间,你甚至可以手动完成。

你应该从这个答案中得到的是,集合的项目需要从 0 开始编号。否则 Hibernate 不会将项目加载到你的集合中。您需要满足 here 中描述的约束条件.

关于hibernate - 之后添加 JPA @OrderColumn 会导致集合错误的空索引列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37432651/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com