Boa noite pessoal, estou usando a versão 3.2.0cr2 do Hibernate e a versão 3.2.0cr1 do Hibernate Annotations.
Estou fazendo uma pequena aplicação para testar a combinação Mentawai + Hibernate. Surgiu um comportamento estranho no Hibernate que não estou sabendo identificar.
O problema é o seguinte…
Tenho a seguinte definição de tabela (Postgres 8.1)
CREATE TABLE tb_contato
(
id_contato serial NOT NULL,
ds_nome varchar(255),
ds_email varchar(255),
ds_endereco varchar(255),
CONSTRAINT tb_contato_pkey PRIMARY KEY (id_contato),
CONSTRAINT ind_unique_nome UNIQUE (ds_nome)
)
WITHOUT OIDS;
ALTER TABLE tb_contato OWNER TO postgres;
Observem que o campo ds_nome tem que ser único.
O seguinte bean de mapeamento:
@Entity
@Table(name="tb_contato")
@javax.persistence.SequenceGenerator(
name="contacts_seq",
sequenceName="tb_contato_id_contato_seq"
)
public class Contact implements Serializable {
public Contact() {
}
private java.lang.Integer id;
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="contacts_seq")
@Column(name="id_contato")
public java.lang.Integer getId() {
return this.id;
}
public void setId(java.lang.Integer id) {
this.id = id;
}
private String name;
@Column(name="ds_nome", unique=true)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
private String email;
@Column(name="ds_email")
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
private String address;
@Column(name="ds_endereco")
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
public boolean equals(Object obj) {
if (obj instanceof Contact) {
Contact contact = (Contact)obj;
if (contact.getId() == this.getId())
return true;
return false;
}
return false;
}
public String toString() {
return "ID: " + this.getId();
}
public int hashCode() {
return this.getId();
}
}
E tenho o seguinte método na minha classe HibernateContactDAO:
...
public void update(Contact contact) throws Exception {
Transaction tx = null;
try {
tx = session.beginTransaction();
Contact c = (Contact)session.load(Contact.class,contact.getId());
BeanUtils.copyProperties(c, contact);
tx.commit();
} catch (Exception e) {
if (tx != null && tx.isActive())
tx.rollback();
throw e;
}
}
...
Vou simular o erro para vcs…
Imaginem que no BD tem 2 registros com ds_nome = “A” e ds_nome= “B” ,repectivamente.
Agora imaginem que o usuário carrega o objeto contact com o ds_nome=“A”, muda o nome para “B” e chama o método update().
Gera um erro de violação de constraint até aí normal.
agora o objeto contact está com ds_nome=“B” (porque ao gerar o erro, o sistema volta para tela de cadastro com o campo input preenchido). O usário dá update novamente. BINGO! Dessa vez não dá erro nenhum.
Só para constar, não estou usando cache de segundo nível.
O que pode estar acontecendo!?
:roll: