Hibernate @ElementCollection – 需要更好的解决方案

我在Web应用程序中使用Hibernate 3.5.a-Final作为ORM-Layer。 我有几个Beans有相同的代码片段,这让我觉得这个设计并不是最好的。 但我无法弄清楚如何在hibernate中实现更好的一个。

要求

  • 有几个类需要在多个语言环境中包含本地化描述
  • 这些需要持久保存到db中
  • 它们必须可以通过所有语言环境的子字符串进行搜索(如果seachstring是任何描述的子字符串,则显示)
  • 本地化描述应该是可查询的,无需加载主对象(通过master-object-id,-type和locale)

当前的解决方案(不解决最后的要求)

每个类都包含一个注释为的HashMap

@ElementCollection(fetch=FetchType.EAGER) @CollectionTable(name = "localized[X]Descriptions", joinColumns = @JoinColumn(name = "id")) @MapKeyJoinColumn(name = "locale") public Map getLocalizedDescriptions() { return localizedDescriptions; } 

[X]是这个class级的名字

对于每个类,它是一个附加表(由hibernate生成)

 create table localized[X]Descriptions ( id integer not null, localizedDescriptions varchar(255), localizedDescriptions_KEY varchar(255), primary key (id, localizedDescriptions_KEY) ) 

由于某种原因, @MapKeyJoinColumn被忽略了……

我更喜欢的是这样的单个表格:

 create table localizedDescriptions ( class varchar(255) not null, id integer not null, locale varchar(50) not null, description varchar(255) not null, primary key (class, id, locale) ) 

如果使用criteria-api(根据我所知,它与@ElementCollection不兼容)可以查询实现,那将是一个很大的@ElementCollection 。 但我无法弄清楚如何实现这一点。 任何指针都会非常受欢迎

我找到了自己的解决方案……

我只是用

 @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="masterClass", discriminatorType=DiscriminatorType.INTEGER) @Table(name="localizedDescriptions") public class LocalizedDescriptions{ private Integer id; private Locale locale; private String description; [Getters, Setters] } 

作为我所有本地化描述的父类,并将其扩展为

 @Entity public class LocalizedSomeDescription extends LocalizedDescription { private Some master; /** * @return the master */ @ManyToOne public Some getMaster() { return master; } 

使用方式如下:

 @Table @Entity public class Some { private Map names = new HashMap(); @OneToMany @JoinColumn(name="master_id") @MapKeyColumn(name="locale") public Map getDescriptions() { return descriptions; } } 

这导致了与我想要的桌面设计非常相似的东西

 create table localizedDescriptionss ( masterClass integer not null, id integer not null auto_increment, locale varchar(255), description varchar(255), master_id integer, primary key (id) ) 

在所有子类中使用mappedBy =“master”可能看起来像是滥用了hibernateinheritance,但是所有其他解决方案都会在每个子类中包含一行,在其他每个子类中都是null,这在我看来就像一个非常糟糕的表设计。 我仍然需要找出discriminatorType=DiscriminatorType.INTEGER的“合理默认值”,如果我需要覆盖该默认值。