【问题标题】:Adding the JPA @OrderColumn afterwards causes null index column for collection error之后添加 JPA @OrderColumn 会导致集合错误的空索引列
【发布时间】:2016-09-22 19:02:08
【问题描述】:

假设我们对实体 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;
}

这个应用程序已经生产了一段时间,保存到数据库中的 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 具有属性“可为空”,默认情况下为 true。但这无济于事。

是否有 JPA 方式来解决这个问题,还是我必须自己在 db 中填充这些空值?

将 JPA 2.1 与 Hibernate 4.3.7 结合使用。

【问题讨论】:

  • 您是否找到了比上面提到的更好的解决方法。理想情况下,它应该按 id 或其他东西对其进行排序,或者自己给出随机列表。
  • 我无法尝试下面答案中给出的解决方案,因为它已经在 4 个月后到达:) (没有抱怨,仍然非常感谢)。我们刚刚使用自定义 sql 脚本填充了这些空值。您是否尝试过以下解决方案?如果是这样,请在这里写下您的经历。

标签: hibernate jpa jpa-2.0 jpa-2.1


【解决方案1】:

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

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

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

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

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

@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 中描述的约束。

【讨论】:

  • 根据上面的描述,可能对每个人来说都不是小事:每个 A 实例的编号必须从 0 开始。换句话说:在 B 的数据库表中,对于指向同一个 A 实例的每一组行,编号必须从 0 开始。
【解决方案2】:

我有一个类似的问题:当我更新现有父项上的子项列表时,休眠似乎没有在 order 列中生成值。我通过在子节点上显式添加 order 列来修复它,就像这样(使用您的示例):

@Entity
public class B{  
  @Column(name = "B_ORDER")
  private int order;

  ...
}

如果我没有这样做,创建 A 记录与B 孩子会正常工作,但更新 A 记录通过添加B 孩子会因null index column for collection: ... 而失败,因为hibernate 不会为B_ORDER 列生成值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    • 2012-01-19
    • 2018-04-13
    • 2019-12-27
    • 2021-07-11
    相关资源
    最近更新 更多