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.
}
And the following DAO for the entity:
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;
}
}
And the following test driver:
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);
}
}
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.
Why is this happening? And more importantly what is a viable solution? How do I configure Hibernate not to insert dupes across multiple driver runs?