你如何使用注释在休眠中映射“地图”?

时间:2010-02-24 17:17:27

标签: java hibernate orm mapping

使用注释如何将实体中的字段映射到给定对象的字符串“Map”(Hashtable)?该对象已注释,其实例已存储在hibernate数据库中。

我找到了使用简单的键和值来定义地图的语法:

<class name="Foo" table="foo">
    ...
    <map role="ages">
         <key column="id"/>
         <index column="name" type="string"/>
         <element column="age" type="string"/>
     </map>
 </class>

奇怪的是,一个实体作为键,一个简单的类型就像这样的值:

<class name="Foo" table="foo">
    ...
  <map role="ages">
    <key column="id"/>
    <index-many-to-many column="person_id" 
         class="Person"/>
    <element column="age" type="string"/>
  </map>
</class>
<class name="Person" table="person">
    ...
    <property name="name" column="name" 
         type="string"/>
</class>

但是我没有看到如何为元素映射的简单键做到这一点,我不知道如何使用注释来做到这一点。

4 个答案:

答案 0 :(得分:39)

您可以简单地使用 JPA注释 @MapKey(请注意,JPA注释与Hibernate注释不同,Hibernate @MapKey会映射包含地图密钥的数据库列,而JPA的注释映射了要用作地图键的属性。

@javax.persistence.OneToMany(cascade = CascadeType.ALL)
@javax.persistence.MapKey(name = "name")
private Map<String, Person> nameToPerson = new HashMap<String, Person>();

答案 1 :(得分:9)

@CollectionOfElements(fetch = FetchType.LAZY)
@JoinTable(name = "JOINTABLE_NAME",
    joinColumns = @JoinColumn(name = "id"))
@MapKey(columns = @Column(name = "name"))
@Column(name = "age")
private Map<String, String> ages = new HashMap<String, String>();

答案 2 :(得分:2)

我知道这个问题已经很老了,但也许这可以帮助别人。

其他可能性是这样的:

@Entity
@Table(name = "PREFERENCE", uniqueConstraints = { @UniqueConstraint(columnNames = { "ID_DOMAIN", "ID_USER", "KEY" })})
public class Preferences {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID", unique = true, nullable = false)
    private Long id;

    @Column(name = "ID_DOMAIN", unique = false, nullable = false")
    private Long domainId;

    @Column (name = "PREFERENCE_KEY")
    @Enumerated(EnumType.STRING)
    private PreferenceKey key;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_USER", referencedColumnName = "ID")
    private User user;
}

and 

@Entity
@Table(name = "USER", uniqueConstraints = { @UniqueConstraint(columnNames = { "ID_DOMAIN", "LOGIN" })})
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID", unique = true, nullable = false)
    private Long id;

    @Column(name = "ID_DOMAIN", unique = false, nullable = false")
    private Long domainId;

    // more fields

    @ElementCollection(fetch = FetchType.LAZY)
    @JoinColumns({@JoinColumn(name = "ID_USER", referencedColumnName = "ID"), @JoinColumn(name = "ID_DOMAIN", referencedColumnName = "ID_DOMAIN")})
    @OneToMany(targetEntity = Preferences.class, fetch = FetchType.LAZY)
    @MapKey(name = "key")
    private Map<PreferenceKey, Preferences> preferencesMap;
}

只生成两个表User和Preferences,请注意PreferenceKey对于用户进入域是唯一的

答案 3 :(得分:1)

您应该使用UserType或UserCollectionType。或者,您可以使用自定义元组。

请参阅hibernate core documentation了解概念,并hibernate annotations documentation了解等效注释方法。

如果这不是您所要求的,请告诉我。