2011-05-22 1 views
3

J'utilise Hibernate 3.5.a-Final comme ORM-Layer dans une application Web. J'ai plusieurs Beans avec le même code-sniplet qui me fait penser que ce design n'est pas le meilleur. Mais je ne peux pas comprendre comment mettre en place un meilleur en hibernation.Hibernate @ElementCollection - Meilleure solution requise

Exigences

  • Plusieurs classes doivent contenir des descriptions localisées dans plusieurs endroits
  • Ceux-ci doivent être persisté dans la db
  • Ils doivent être recherchés par sous-chaîne pour tous les paramètres régionaux (montrer si la seachstring est une sous-chaîne de n'importe quelle description)
  • Les descriptions localisées doivent pouvoir être interrogées sans charger l'objet principal (par l'identificateur d'objet maître, le type et l'environnement local)

solution actuelle (ne résout pas la dernière exigence)

Chaque classe contient un HashMap annoté

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

[X] beeing le nom de la classe

pour chaque classe la est une table supplémentaire (générée par hibernate)

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

Pour une raison quelconque, le @MapKeyJoinColumn est ignorée ...

Ce que je préfère serait une seule table comme ceci:

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) 
) 

Ce serait un gros plus si la mise en œuvre serait en utilisant interrogeable des critères-api (qui ISN n'est pas compatible avec @ElementCollection s pour autant que je sache). Mais je ne peux pas comprendre comment implémenter ceci. Tous les pointeurs seraient bienvenus

Répondre

2

J'ai trouvé ma propre solution ...

je viens d'utiliser

@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] 
} 

comme ma classe parent pour toutes les descriptions localisées et étends comme

@Entity 
public class LocalizedSomeDescription extends LocalizedDescription { 

    private Some master; 

    /** 
    * @return the master 
    */ 
    @ManyToOne 
    public Some getMaster() { 
     return master; 
    } 

Ce qui s'utilise comme ceci:

@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; 
    } 

} 

Il en résulte quelque chose de très semblable à ma conception de table destiné

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) 
) 

utilisant mappedBy = « maître » dans toutes les sous-classes peut sembler un abus de l'héritage de mise en veille prolongée, mais toutes les autres solutions comprennent une ligne par sous-classe qui serait null dans tous les autres, ce qui me semble être un très mauvais design de table. Je dois encore savoir quel est le «défaut par défaut» pour un discriminatorType=DiscriminatorType.INTEGER et si j'ai besoin de remplacer cette valeur par défaut.

Questions connexes