在Hibernate中映射每个项目对象的多行

时间:2010-08-27 15:09:23

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

我遇到了某种非呃正统的设计,我不太清楚如何处理它。我想要映射的表格如下:

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)组合都有单独的实例。

显然,这不是很正常化。最糟糕的情况是,我设置了一些规范化的额外表并将所有内容复制过来,但我想知道是否有人可以建议一种合理的方法将这些信息直接传递给hibernate支持的对象?如果需要某种String属性包。

我正在使用hibernate-annotations btw。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

由于ID是另一个表的外键(让我们调用该表'container'),因此可以将其映射为带有复合键的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>