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.
So:
- 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?
Thanks in advance!