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
的“合理默认值”,如果我需要覆盖该默认值。