Thomas Stubbe
Thomas Stubbe

Reputation: 1985

Hibernate: Map Two Columns to a HashMap's Key and Value

I have a database with an object, which has translations.

There are 2 tables: table Object which has id and more properties and table 'object_translation' which has object_id, language (varchar) and translation (varchar)

I would like to map this to

public class Object {
    private Map<Language, String> translations
}

Where language is an enum in code and a string in the DB.

Is this possible with annotations? or do I need to create either Collection<QuestionTranslation> or write my own hibernate mapping functions in the DAO (I'm using spring-data, so I would prefer to keep it nice and clean as interfaces and annotations)

Versions: spring-boot 2 with provided hibernate from spring-boot-starter:

spring boot: <version>2.0.3.RELEASE</version>
<hibernate.version>5.2.17.Final</hibernate.version>
<hibernate-jpa-2.1-api.version>1.0.2.Final</hibernate-jpa-2.1-api.version>

So far I have this:

@OneToMany
@JoinTable(name = "object_translation", joinColumns = {@JoinColumn(name = "object_id", referencedColumnName = "id")})
@MapKey(name = "language")
@MapKeyEnumerated(EnumType.STRING)
private Map<Language, String> translations;

But how do I map the value as well? (for clarification: the String value should be the translation column in the DB)

Because I don't have a primary-key, this should theoretically be possible?

Thanks in advance!

Upvotes: 4

Views: 4098

Answers (2)

Thomas Stubbe
Thomas Stubbe

Reputation: 1985

I managed to fix it =)

You shouldn't use @OneToMany.

What I used:

public class Object {

    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "object_translation",
                 foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_object_translation_object"),
                 joinColumns = @JoinColumn(name = "object_id"))
    @MapKeyColumn(name = "language", nullable = false)
    @MapKeyEnumerated(EnumType.STRING)
    @Column(name = "translation", nullable = false)
    private Map<Language, String> translations;
}

Upvotes: 2

user3392782
user3392782

Reputation: 181

It is not achievable from ORM perspective. There is no way to tell ORM framework to map String to Translation column.

The best way to achieve this would be by retrieving the rows from Object_Translation as a List or Set using @OneToMany or @ManyToMany with mappedBy and then writing your custom to convert them to a map.

Upvotes: 0

Related Questions