Hibernate 映射具有空值的复合键

问题描述 投票:0回答:7

使用 Hibernate,您可以创建一个复合 ID,其中映射到 ID 的列之一可以具有空值吗?

这是为了处理具有唯一键的遗留表,该键可以具有空值但没有主键。

我意识到我可以向表中添加一个新的主键列,但我想知道是否有任何方法可以避免这样做。

java hibernate
7个回答
15
投票

不。主键不能为空。


8
投票

您不会收到错误,但 Hibernate 将无法将复合列具有 NULL 值的行映射到您的实体。这意味着您得到结果中带有 NULL 值的实体。


6
投票

不幸的是,没有。我要么必须使用解决方法:

我将复合 Id 用于视图(!不是表),其中行可以由 2 列(A,B)精确标识。尽管列之一 (B) 可以具有空值以及正整数。 所以我的解决方法是我在视图中创建了一个新的列:“BKey”,并且我的视图被编写为如果 B 为 null,则 BKey 的值为 -1,否则 BKey = B。(只有正整数出现在 B 和 null 中)。我还更改了我的组合 id 实现以使用 BKey 而不是 B。 希望它对某人有帮助..


0
投票

这是不可取的。您可以使用视图和地图来代替吗?如果您遇到遗留数据问题,可以使用 COALESCE 来提供默认值。我们在使用复合键时遇到了很多麻烦,我想空值会导致更多问题。


0
投票

对于复合键(假设数据库允许 PK 中存在空值),您最多可以有 number_of_cols^2 - 1 个包含空值的条目(例如,对于 2 列的复合键,您可以有 3 行的主键为空,第四个是没有 null 的 PK)。


0
投票

我遇到了映射到 OpenEdge Progress 数据库的模型实体的问题,我无法修改该数据库。它有 3 个不同的 ID 列,基本上构成了主键。

我想出了一个解决方法,这样我至少可以获得数据,即使在我看来它不是很漂亮。

在扩展了

JpaRepository<MyEntity, Long>
的 Repository 类中,我添加了一个返回
List<Object[]>
的新方法。例如:

@Query(
value="SELECT * FROM pub.\"mytable\" WHERE \"id-one\" = ?1 AND \"id-two\" = ?2 AND \"id-three\" is null", 
nativeQuery=true
)
List<Object[]> getRecordsAsObject(Long aIdOne, Long aIdTwo);

然后在我的服务类中,我通过从对象数组中提取数据来手动创建模型记录。

getRecordsAsObject(myIdOne, myIdTwo).forEach(aRecord -> {
   MyEntity myEntity = new MyEntity();
   myEntity.setIdOne((Long) aRecord[0]);
   myEntity.setIdTwo((Long) aRecord[1]);
   myEntity.setOtherValue((String) aRecord[2]);
   process(myEntity);
});

这至少可以帮助我从表中提取数据。我不知道它在进一步保留/保存/更新表中的记录方面会做任何事情。


-2
投票

你为什么要这么做?您的复合 ID 应该映射表的主键,在键中放入空值听起来并不明智,不是吗?

编辑: Hibernate 不允许这样做;您可以将属性放在键之外,并稍微调整 DAO 以在必要时考虑该字段

© www.soinside.com 2019 - 2024. All rights reserved.