OneToMany + MapKeyJoinColumn doesn't work for me, please suggest what I'm doing wrong.
I'm using JPA 2.0 + Hibernate 3.6.1 And want to map following tables:

To Classes:
@Entity
public class Question {
    // id and other fields
    @OneToMany(mappedBy="question", cascade = CascadeType.ALL)
    @MapKeyJoinColumn(name="language_id")
    private Map<Language, Statement> statements =
        new HashMap<Language, Statement>();
}
@Entity
public class Statement {
    @Id
    private Long id;
    @ManyToOne
    @JoinColumn(name = "language_id", nullable = true)
    private Language language;
    @ManyToOne
    @JoinColumn(name = "question_id", nullable = false)
    private Question question;
    @Column(name = "message")
    private String message;
}
@Entity
public class Language {
    @Id
    private Long id;
    @Column(name = "name")
    private String name;
}
But it doesn't work. EntityManager persists it correctly, but when I retrieve Question, in it's statements map there is only one language-to-null entry. Please, help
Edit1: Strange, but when I preload all Languages, like this:
String sql = "select l from Language l";
List languages = entityManager.createQuery(sql, Language.class).getResultList();
then it works!
Does anybody know how to make hibernate automatically load all objects of certain class?
In fact, the id property in your class Statement must be a composite primary key. You do not need a statement_id in your table Statement. The primary key is composed of both language_id and question_id.
Try that :
    @Entity
    public class Statement implements Serializable {
        private static final long serialVersionUID = 1L;
        @EmbeddedId
        private StatementId id = new StatementId();
        @Column(name = "message")
        private String message;
    }
    @Embeddable
    private static class StatementId implements Serializable {
        private static final long serialVersionUID = 1L;
        StatementId(){}
        @ManyToOne
        private Question product;
        @ManyToOne
        private Language language;
    }
And do not forget the fetchType in Question in order to avoid LazyInitializationExceptions.
public class Question {
    @OneToMany(mappedBy="id.question", fetch=FetchType.EAGER)
    @MapKeyJoinColumn(name="language_id")
    private Map<Language, Statement> statements = new HashMap<Language, Statement>();
}
Hope it will help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With