使用ManyToMany的Hibernate AnnotationException?

时间:2013-11-10 03:21:56

标签: java hibernate exception orm

我第一次尝试Hibernate。我有2个基本表:

words
    word_id             ==>     21939
    word_text           ==>     "fast"
    word_length         ==>     4
    word_definition     ==>     "Something that is quick."

word_types
    word_types_id       ==>     2
    word_type_label     ==>     "Adverb"
    word_type_description   ==> "Describes a verb."
    word_type_tag       ==>     "ADVERB"

words表与自身具有特殊的多对多关系。单词有同义词,也就是其他单词。他们也有反义词,也就是说。理想情况下,Hibernate会为我创建hibernate.hbm2ddl.auto updatesynonymsantonyms表,它将保存单词及其同义词之间的多对多关系,和单词及其反义词。这个的Java模型是:

@Entity
@AttributeOverrides({
@AttributeOverride(name="id", column=@Column(name="word_id"))
})
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Table(name="words")
public class Word {
    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @Column(name="word_text")
    private String text;

    @Column(name="word_length")
    private Integer length;

    @ManyToOne
    @JoinColumn(name="word_type_id", referencedColumnName="word_type_id")
    private WordType wordType;

    @Column(name="word_definition")
    private String definition;

    @ManyToMany()
    private List<Word> synonyms;        // "quick", "nimble"

    @ManyToMany()
    private List<Word> antonyms;        // "slow", "sluggish"
}

@Entity
@AttributeOverrides({
@AttributeOverride(name="id", column=@Column(name="word_type_id")),
@AttributeOverride(name="label", column=@Column(name="word_type_label")),
@AttributeOverride(name="description", column=@Column(name="word_type_description")),
@AttributeOverride(name="tag", column=@Column(name="word_type_tag"))
})
private class WordType {
    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    private String label;
    private String description;
    private String tag;
}

然后WordDAOWord实例持久保存到我的H2 DB:

public Word doPersist(Word word) {
    Session session = getDaoUtils().newSessionFactory().openSession();
    Word returnable = null;
    Transaction transaction = null;

    try {
        transaction = session.beginTransaction();

        session.saveOrUpdate(word);

        transaction.commit();
    } catch(Throwable throwable) {
        transaction.rollback();

        throw new RuntimeException(throwable);
    } finally {
        session.close();
    }

    return returnable;
}

然后我写了一个小测试驱动程序:

public class HibernateTester {
    public static void main(String[] args) {
        Word fast = new Word("fast", 4, WordType.Adverb, "A fast thing.", null, null);
        Word slow = new Word("slow", 4, WordType.Adverb, "A slow thing.", null, null);

        List<Word> synonyms = new ArrayList<Word>();
        List<Word> antonyms = new ArrayList<Word>();

        synonyms.add(fast);
        antonyms.add(slow);

        Word quick = new Word("quick", 5, WordType.Adverb, "A quick thing.", synonyms, antonyms);

        WordDAO wordDAO = new WordDAO();

        wordDAO.doPersist(quick);
    }
}

当我运行它时,我得到以下异常:

INFO: HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
Exception in thread "main" org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: 
net.me.myapp.common.dal.dto.WordDTO.synonyms[net.me.myapp.common.model.Word]
    at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1059)
    at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:733)
    at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:668)
    at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:69)
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1611)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1369)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1756)
    at net.me.myapp.common.dal.dao.DAOUtils.newSessionFactory(DAOUtils.java:21)
    at net.me.myapp.common.dal.dao.WordDAO.doPersist(WordDAO.java:14)
    at net.me.myapp.tools.wordloader.HibernateTester.main(HibernateTester.java:25)

任何想法为什么?提前谢谢!

1 个答案:

答案 0 :(得分:-1)

你需要定义到实体类的映射。这解释得更好 http://www.tutorialspoint.com/hibernate/hibernate_examples.htm

如果在定义会话工厂时使用spring,则需要提供实体类。

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="annotatedClasses">
    <list>
        <value>net.me.myapp.common.model.Word</value>
    </list>
</bean>