Hibernate @ElementCollection - Better Solution Required

I am using Hibernate 3.5.a-Final as an ORM-Layer in a web application. I have several Beans with the same code sniplet, which makes me think that this design is not the best. But I can’t figure out how to implement the best in sleep mode.

Requirements

  • Several classes must contain localized descriptions in several locales.
  • They must be saved in db
  • They should be searchable by substring for all locales (if the binding string is a substring of any description)
  • Localized descriptions should be available for request without loading the master object (by identifier-master-type, type and language)

Current solution (does not solve the last requirement)

Each class contains a HashMap annotated as

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

[X] - class name

For each class, this is an extra table (generated by sleeping)

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

For some reason @MapKeyJoinColumn ignored ...

I would prefer a table like this:

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

It would be a big plus if the implementation were requested using the api criterion (which, as far as I know, is not compatible with @ElementCollection ). But I can’t figure out how to implement this. Any pointers would be very welcome

+3
source share
1 answer

I found my solution ...

I just use

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

as my parent class for all localized descriptions and extend it as

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

Used like this:

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

This leads to something very similar to my intended table design.

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

using mappedBy = "master" in all subclasses may seem like an abuse of hibernation, but all other solutions will include one row for each subclass, which will be zero in every other, which seems like a very bad table design. I still need to find out what the “reasonable default value” is for discriminatorType=DiscriminatorType.INTEGER , and if I need to override this default value.

+2
source

Source: https://habr.com/ru/post/1413712/


All Articles