休眠位数组到实体映射

Posted

技术标签:

【中文标题】休眠位数组到实体映射【英文标题】:Hibernate bit array to entity mapping 【发布时间】:2010-04-26 14:00:30 【问题描述】:

我正在尝试使用 Hibernate 3.5 将规范化的 Java 模型映射到旧数据库模式。一个特定的表将一对多关系中的外键编码为位数组列。

考虑表格personclub,它们描述了人们与俱乐部的关系:

person: .----.------.    club: .----.---------.---------------------------.
        | id | name |          | id |   name  | members | binary(members) |
        |----+------|          |----+---------|---------+-----------------|
        |  1 | Bob  |          | 10 | Cricket |       0 |             000 |
        |  2 | Joe  |          | 11 | Tennis  |       5 |             101 | 
        |  3 | Sue  |          | 12 | Cooking |       7 |             111 |   
        '----'------'          | 13 | Golf    |       3 |             100 |
                               '----'---------'---------'-----------------'

所以希望很明显person.id被用作位数组club.members中的位索引:

.---.---.---.
| S | J | B |
| u | o | o |
| e | e | b |
|---+---+---|
| 1 | 0 | 1 |
'---'---'---'

在此示例中,members 列告诉我们:

没有人是 Cricket 的成员 --- 没有设置标志 Bob/Sue -> 网球 --- 位置 1 和 3 的标志已设置 Bob/Sue/Joe -> 烹饪 --- 位置 1、2 和 3 的标志已设置 Sue -> Golf --- 位置 3 的标志已设置

现在,对于此示例,可以使用连接表来代替,这将简化问题并避免许多潜在问题 - 例如:members 的最大范围设置了people 行数的上限。但是,我被这个架构卡住了,而且似乎有一些因素支持使用位数组列。

在我的 Java 域中,我想用这样的实体来建模这个模式:

class Person 
    private int id;
    private String name;
    ...


class Club 
    private Set<Person> members;
    private int id;
    private String name;
    ...

我假设我必须使用 UserType 实现,但找不到任何示例,其中用户类型描述的项目是对实体的引用 - 不是文字字段值 - 或其组合。此外,我知道我必须考虑在加载 club 实例时如何获取 person 实体。

谁能告诉我如何使用 Hibernate 驯服这个遗留架构?

更新

我最近不得不在旧数据库中重新审视这种类型的映射。这一次很明显,我们等效的members 表实际上是一个静态集,可以硬编码为Enum。通过这种简化,实现在位数组和一组枚举之间转换的 Hibernate UserType 相当简单。

【问题讨论】:

你有没有想过这个问题? 【参考方案1】:

我从未遇到过这种情况,但我认为您需要实现自定义 UserCollectionType(参见 Hibernate Core 文档中的 5.2.3. Custom value types 章节),UserCollectionType扩展点,可以用来支持你喜欢的任何该死的集合和集合语义

我不确定注释对它们的支持程度如何(根据HHH-4417,您可能必须使用 hack)。在 IMO 中使用 hbm.xml 是个好主意。

更多指针/讨论:

https://forum.hibernate.org/viewtopic.php?f=9&t=938522&start=0 http://www.javalobby.org/java/forums/m91832311.html(不同的情况,但可能会让您知道如何开始)

【讨论】:

不幸的是,UserCollectionType 在这种情况下似乎没有多大用处。其目的是允许 Hibernate 使用从连接中加载的一堆实体填充您选择的 Collection。我的情况完全不同——我需要让 Hibernate 将字段中的值解释为实体的一组键,然后为这些实体创建代理,然后将这些代理添加到 Collection。无论如何 - 谢谢你的建议! 您是否考虑过将数据库中的数据转换为临时表,然后从该简化聚合创建映射?你可能只能阅读……只是一个想法。

以上是关于休眠位数组到实体映射的主要内容,如果未能解决你的问题,请参考以下文章

休眠:覆盖(实体)超类的 OneToMany 映射字段?

我可以对未映射到表的实体使用休眠查询语言吗?

@OneToMany 映射休眠中的集合

休眠查询以匹配映射实体集合与给定集合中的至少一个元素,多对多关系

休眠双向多对多映射建议!

使用实体框架/休眠与 sql2008 地理数据类型