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

时间:2011-05-22 13:31:16

标签: java hibernate orm jpa

我在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<Locale, String> getLocalizedDescriptions() {
    return localizedDescriptions;
}

[X]是该课程的名称

对于每个类,这是一个附加表(由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不兼容)可以查询实现,那将是一个很大的优势。 但我无法弄清楚如何实现这一点。任何指针都会非常受欢迎

1 个答案:

答案 0 :(得分:2)

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

我只是用

@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<Locale, LocalizedSomeDescription> names = new HashMap<Locale, LocalizedSomeDescription>();

    @OneToMany
    @JoinColumn(name="master_id")
    @MapKeyColumn(name="locale")
    public Map<Locale, LocalizedSomeDescription> 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”可能看起来像是滥用了hibernate继承,但是所有其他解决方案都会在每个子类中包含一行,在每个子类中都是null,这在我看来就像一个非常糟糕的表设计。我仍然需要找出discriminatorType=DiscriminatorType.INTEGER的“合理默认值”,如果我需要覆盖该默认值。