JPA 2.0 Hibernate @OneToMany + @MapKeyJoinColumn

6

我的OneToMany + MapKeyJoinColumn不起作用,请建议我做错了什么。

我正在使用JPA 2.0 + Hibernate 3.6.1,并希望映射以下表:


问题到语句到语言关系


到类:



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

但是它不起作用。EntityManager 正确地持久化了它,但是当我检索 Question 时,在它的语句映射中只有一个语言到 null 的条目。请帮忙。


Edit1: 奇怪的是,当我预加载所有语言,像这样:


String sql = "select l from Language l";
List languages = entityManager.createQuery(sql, Language.class).getResultList();

然后它就可以工作了!
有人知道如何让Hibernate自动加载某个类的所有对象吗?


1
类似的设置对我来说运行良好。你能展示一下你的测试代码吗? - axtavt
你使用的是 Hibernate 3.6.1 还是其他什么? - jnr
我是这样测试的:手动向数据库插入一些数据,然后在Junit测试中调用像<code>entityManager.find(Question.class, 463L);</code>这样的语句。 - jnr
3个回答

3
事实上,您在类Statement中的id属性必须是一个复合主键。您不需要在表Statement中使用statement_id。主键由language_id和question_id组成。
尝试一下:
    @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;

    }

不要忘记在Question中设置fetchType,以避免LazyInitializationExceptions。

public class Question {

    @OneToMany(mappedBy="id.question", fetch=FetchType.EAGER)
    @MapKeyJoinColumn(name="language_id")
    private Map<Language, Statement> statements = new HashMap<Language, Statement>();
}

希望这能有所帮助。

1

1

你是否正在使用二级缓存?你的对象是否已经是会话的一部分(一级缓存)?尝试执行session clear()。


不,我不使用二级缓存。问题出现在会话中没有任何内容(刚开始时),当会话中没有语言实例时。 - jnr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接