为什么每次运行我的应用程序时,Hibernate都会插入重复的记录? [英] Why is Hibernate inserting duplicate records every time I run my app?

查看:166
本文介绍了为什么每次运行我的应用程序时,Hibernate都会插入重复的记录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Hibernate 4.2.3 final。我有以下实体:

Using Hibernate 4.2.3 final. I have the following entity:

@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)
    protected Long id;

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

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

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="word_type_id", referencedColumnName="word_type_id")
    private WordType type;

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

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "synonyms", joinColumns = @JoinColumn(name = "word_id"), inverseJoinColumns = @JoinColumn(name = "synonym_id"))
    private List<Word> synonyms;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "antonyms", joinColumns = @JoinColumn(name = "word_id"), inverseJoinColumns = @JoinColumn(name = "antonym_id"))
    private List<Word> antonyms;

    // ctor, getters/setters, etc.
}

和实体的以下DAO:

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

        try {
            transaction = session.beginTransaction();

            session.saveOrUpdate(word);
            returnable = word;

            transaction.commit();
        } catch(Throwable throwable) {
            transaction.rollback();
            throw new RuntimeException(throwable);
        } finally {
            session.close();
    }

        // Return any result, if applicable.
        return returnable;
    }
}

以下测试驱动程序:

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

        quick.addSynonym(fast);
        quick.addAntonym(slow);

        WordDAO wordDAO = new WordDAO();

        wordDAO.saveWord(quick);
    }
}

如果我运行 HibernateTester 多次,我每次将3个词插入到我的DB表中。所以如果我从我的单词表中删除每个记录,然后运行测试驱动程序4次,我将在表中有12个单词(4个运行x 3个记录/运行)。因为我使用 Session#saveOrUpdate ,所以我希望Hibernate足够聪明才能知道DB中已经存在这些实体,并阻止它们被插入。

If I run HibernateTester multiple times, I it inserts the 3 words into my DB tables each time. So if I delete every record from my words table, and then run the test driver 4 times, I'll have 12 words in the table (4 runs x 3 records/run). Since I'm using Session#saveOrUpdate, I would have expected Hibernate to be smart enough to figure out that the entities already exist in the DB, and prevent them from being inserted.

所以:


  1. 为什么会这样?更重要的是,

  2. 什么是可行的解决方案?如何配置Hibernate不要在多个驱动程序运行中插入副本?

提前感谢!

推荐答案

saveOrUpdate()如果实体没有ID,则保存实体,如果已经有一个ID。你总是传递没有ID的实体,所以Hibernate创建实体。每一次。

saveOrUpdate() saves the entity if it doesn't have an ID, and updates it if it already has an ID. You always pass entities which don't have an ID, so Hibernate creates the entity. every time.

唯一标识一个实体的是它的ID。不是其名称,文字或任何其他属性。

The only thing that identifies an entity is its ID. Not its name, text, or whatever other attribute.

这篇关于为什么每次运行我的应用程序时,Hibernate都会插入重复的记录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆