如何将 class 的属性定义为地图的键?
How to define an attribute of a class as key for a map?
第一次用Maps和JPA做持久化。
我在概念层面也有点迷失了自己。
我有一个对象 (poi) none,一个或多个不同语言的描述。
我希望 poi 对象有一个地图 [lang, description]
@Entity
public class Poi {
@Id
@Column(name = "id")
private Long id;
@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "description_poi_mapping",
joinColumns = {@JoinColumn(name = "poi_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "description_id", referencedColumnName = "id")})
@MapKeyJoinColumn(name = "lang_id")
@MapKey
private Map<Lang, Description> descriptionCourte;
描述:
@Entity
public class Description {
@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String label;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "lang_id")
private Lang lang;
语言:
@Entity
public class Lang {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
@Column(name = "id")
private Long id;
@Column(name = "label")
private String label;
因此,描述包含附加到语言的标签(fr、en、it、de、...)
我希望我能做到,上图;
> poi.getDescriptionCourte().get("en") or
> poi.getDescriptionCourte().get("fr")
基本上,地图的关键是语言标签(如果存在)。如果“poi”有1条英文描述和1条法文描述,那么我的地图必须有2条key值为“fr”或“en”的记录(为“lang”记录的标签)
当然,目标是能够重用 lang class 用于其他描述。
排除我现在的结果完全不是我想要的,这里是:
你能帮帮我吗?
谢谢你。
这不是直接可能的。您可以实现 Lang
的 equals
/hashCode
以便仅使用标签,然后您可以访问 poi.getDescriptionCourte().get(new Lang("fr"))
之类的元素或在单独的方法 [=14= 中将其抽象出来] 这是我之前写的。请注意,尽管这需要您获取所有 Lang 对象,即在当前 session/entityManager 中具有它们的托管表示,所以我建议您使用 Locale
代替,它由 Hibernate 映射到仅包含的字符串列本地代码。您还可以将 Lang
建模为 @Embeddable
或提供在 String
和 Lang
之间转换的 AttributeConverter
。这样,就不需要额外的 joins/fetches。
第一次用Maps和JPA做持久化。 我在概念层面也有点迷失了自己。
我有一个对象 (poi) none,一个或多个不同语言的描述。 我希望 poi 对象有一个地图 [lang, description]
@Entity
public class Poi {
@Id
@Column(name = "id")
private Long id;
@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "description_poi_mapping",
joinColumns = {@JoinColumn(name = "poi_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "description_id", referencedColumnName = "id")})
@MapKeyJoinColumn(name = "lang_id")
@MapKey
private Map<Lang, Description> descriptionCourte;
描述:
@Entity
public class Description {
@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String label;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "lang_id")
private Lang lang;
语言:
@Entity
public class Lang {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
@Column(name = "id")
private Long id;
@Column(name = "label")
private String label;
因此,描述包含附加到语言的标签(fr、en、it、de、...) 我希望我能做到,上图;
> poi.getDescriptionCourte().get("en") or
> poi.getDescriptionCourte().get("fr")
基本上,地图的关键是语言标签(如果存在)。如果“poi”有1条英文描述和1条法文描述,那么我的地图必须有2条key值为“fr”或“en”的记录(为“lang”记录的标签)
当然,目标是能够重用 lang class 用于其他描述。
排除我现在的结果完全不是我想要的,这里是:
你能帮帮我吗?
谢谢你。
这不是直接可能的。您可以实现 Lang
的 equals
/hashCode
以便仅使用标签,然后您可以访问 poi.getDescriptionCourte().get(new Lang("fr"))
之类的元素或在单独的方法 [=14= 中将其抽象出来] 这是我之前写的。请注意,尽管这需要您获取所有 Lang 对象,即在当前 session/entityManager 中具有它们的托管表示,所以我建议您使用 Locale
代替,它由 Hibernate 映射到仅包含的字符串列本地代码。您还可以将 Lang
建模为 @Embeddable
或提供在 String
和 Lang
之间转换的 AttributeConverter
。这样,就不需要额外的 joins/fetches。