【问题标题】:Mapping multiple-row per item objects in Hibernate在 Hibernate 中映射每个项目对象的多行
【发布时间】:2011-04-04 20:57:42
【问题描述】:

我遇到了一个,呃,非正统的设计,我不太确定如何处理它。我要映射的表如下所示:

TABLE example {
    ID INT,
    CATEGORY VARCHAR,
    PROPERTY VARCHAR,
    VALUE VARCHAR);

一个 id 可以有几行(显然,不是主键)。例如,它可能如下所示:

# ID  CATEGORY     PROPERTY VALUE
  1   general_info name     order 1
  1   general_info date     1/1/2009
  ...

每个 ID 可能有几个不同的类别。对于任何给定的(id、类别)组合,属性名称都是唯一的。

(编辑)ID 字段是不同表中对象的外键。我需要能够从这些对象中获取存储在此表中的各种属性,仅使用 ID 字段。如果复合键是要走的路,我该如何链接它们?

(EDIT2)我还认为您在这里缺少的细节是第一列中具有相同 ID 的所有数据在概念上属于同一个对象。我不希望每个 (ID,CATEGORY) 组合都有一个单独的实例。

显然,这不是很规范。在最坏的情况下,我设置了一些额外的表,这些表已标准化并复制所有内容,但我想知道是否有人可以建议一种明智的方法将这些信息直接放入休眠支持的对象中?如有必要,在某种字符串属性包中。

顺便说一句,我正在使用休眠注释。

【问题讨论】:

  • @PascalThivent 谢谢,我添加了一些额外的信息。我不认为这是一个简单的复合关键问题,而是关于如何使这项工作受欢迎的建议。

标签: java hibernate orm composite-key hibernate-annotations


【解决方案1】:

使用具有 ID、CATEGORY 和 PROPERTY 的复合键。请参阅 Multiple key in hibernate how to?JPA - Entity design problem 了解如何实现此功能的示例(@EmbeddedId 是关键!)

【讨论】:

    【解决方案2】:

    由于 ID 是另一个表的外键(我们称该表为“容器”),因此可以将其映射为带有复合键的 Map。

    例子:

    public class Container {
        private int id;
        private Map<Key,String> values = new HashMap<Key,String>();
    
        public String getValue(String category, String property) {
            return values.get(new Key(category, property));
        }
    
        public void setValue(String category, String property, String value) {
            values.put(new Key(category, property), value);
        }
    
        public static class Key {
            private String category;
            private String property;
    
            public Key(String cat, String prop) {
                category = cat;
                property = prop;
            }
    
            public String getCategory() {
                return category;
            }
    
            public String getProperty() {
                return property;
            }
    
            @Override
            public boolean equals(Object obj) {
                if (!(obj instanceof Key)) {
                    return false;
                }
                Key k = (Key)obj;
                return category.equals(k.category) && property.equals(k.property);
            }
    
            @Override
            public int hashCode() {
                return 37*category.hashCode() + property.hashCode();
            }
        }
    }
    

    映射:

    <class name="Container" table="container">
        <id column="ID" name="id">
            <generator class="native"/>
        </id>
        <map cascade="all-delete-orphan" name="values" table="example">
            <key column="ID"/>
            <composite-map-key class="Container$Key">
                <key-property name="category" type="string" column="CATEGORY"/>
                <key-property name="property" type="string" column="PROPERTY"/>
            </composite-map-key>
            <element type="string" column="VALUE"/>
        </map>
    </class>
    

    【讨论】:

    • 如果我没记错的话,这可能适用于最新的休眠注释,但不适用于任何 JPA1 注释?
    • 谢谢。我最终避免了元素的集合,但做了一些非常相似的事情,将属性映射为一个带有嵌入键的类并使用@OneToMany(mappedBy="key.id")。显然子表达式是合法的,而且似乎可以工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-24
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多