Usando o Hibernate 4.2.3 final. Eu tenho a seguinte entidade:
@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. }
E o seguinte DAO para a entidade:
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; } }
E o seguinte driver de teste:
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); } }
Se eu rodar o HibernateTester
várias vezes, ele insere as 3 palavras nas minhas tabelas DB a cada vez. Portanto, se eu excluir todos os registros da minha tabela de words
e, em seguida, executar o driver de teste 4 vezes, terei 12 palavras na tabela (4 execuções x 3 registros / executar). Como estou usando o Session#saveOrUpdate
, eu esperaria que o Hibernate fosse inteligente o bastante para descobrir que as entidades já existiam no database e impedi-las de serem inseridas.
Assim:
Desde já, obrigado!
saveOrUpdate()
salva a entidade se ela não tiver um ID e a atualiza se já tiver um ID. Você sempre passa entidades que não possuem um ID, então o Hibernate cria a entidade. toda vez.
A única coisa que identifica uma entidade é o seu ID. Não é seu nome, texto ou qualquer outro atributo.