为什么每次运行我的应用程序时Hibernate都会插入重复的记录?

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

@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 synonyms; @ManyToMany(cascade = CascadeType.ALL) @JoinTable(name = "antonyms", joinColumns = @JoinColumn(name = "word_id"), inverseJoinColumns = @JoinColumn(name = "antonym_id")) private List 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(), new ArrayList()); Word slow = new Word("slow", 4, WordType.Adverb, "A slow thing.", new ArrayList(), new ArrayList()); Word quick = new Word("quick", 5, WordType.Adverb, "A quick thing.", new ArrayList(), new ArrayList()); quick.addSynonym(fast); quick.addAntonym(slow); WordDAO wordDAO = new WordDAO(); wordDAO.saveWord(quick); } } 

如果我多次运行HibernateTester ,我每次都会将3个单词插入到我的数据库表中。 因此,如果我从我的words表中删除每个记录,然后运行测试驱动程序4次,我将在表中有12个单词(4个运行x 3个记录/运行)。 因为我正在使用Session#saveOrUpdate ,所以我希望Hibernate足够聪明,可以发现实体已经存在于DB中,并阻止它们被插入。

所以:

  1. 为什么会这样? 更重要的是
  2. 什么是可行的解决方案? 如何配置Hibernate不在多个驱动程序运行中插入du​​pe?

提前致谢!

如果实体没有ID, saveOrUpdate()将保存实体,如果已有ID,则更新实体。 您总是传递没有ID的实体,因此Hibernate会创建实体。 每次。

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