Problema em relacionamento @OneToMany

Olá, estou passando por um estranho problema com um relacionamento bidirecional @OneToMany e @ManyToOne entre as classes Contato e FaleConosco.

Seguem as classes com os relacionamentos:

[code]@SuppressWarnings(“serial”)
@Entity
@Table(name = “prt_contato”)
@SequenceGenerator(name = “seqPrtContato”, sequenceName = “seq_prt_contato”, allocationSize = 1)
public class Contato implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqPrtContato")
@Column(nullable = false)
private Integer idContato;

@Column(nullable = false, length = 50)
private String nome;

@Column(nullable = false, length = 100)
private String emailDestinatario;

@Column(nullable = false)
private Idioma idioma;

@OneToMany(mappedBy = "contato")
private List<FaleConosco> faleConoscos = new ArrayList<FaleConosco>();

@Version
private Integer optlock;

public Integer getIdContato() {
	return idContato;
}

public void setIdContato(Integer idContato) {
	this.idContato = idContato;
}

public String getNome() {
	return nome;
}

public void setNome(String nome) {
	this.nome = nome;
}

public String getEmailDestinatario() {
	return emailDestinatario;
}

public void setEmailDestinatario(String emailDestinatario) {
	this.emailDestinatario = emailDestinatario;
}

public Idioma getIdioma() {
	return idioma;
}

public void setIdioma(Idioma idioma) {
	this.idioma = idioma;
}

public Integer getOptlock() {
	return optlock;
}

public void setOptlock(Integer optlock) {
	this.optlock = optlock;
}

public List<FaleConosco> getFaleConoscos() {
	return faleConoscos;
}

public void setFaleConoscos(List<FaleConosco> faleConoscos) {
	this.faleConoscos = faleConoscos;
}

@Override
public int hashCode() {
	final int prime = 31;
	int result = 1;
	result = prime * result + ((emailDestinatario == null) ? 0 : emailDestinatario.hashCode());
	result = prime * result + ((idioma == null) ? 0 : idioma.hashCode());
	result = prime * result + ((nome == null) ? 0 : nome.hashCode());
	return result;
}

@Override
public boolean equals(Object obj) {
	if (this == obj) {
		return true;
	}
	if (obj == null) {
		return false;
	}
	if (!(obj instanceof Contato)) {
		return false;
	}
	Contato other = (Contato) obj;
	if (emailDestinatario == null) {
		if (other.emailDestinatario != null) {
			return false;
		}
	} else if (!emailDestinatario.equals(other.emailDestinatario)) {
		return false;
	}
	if (idioma != other.idioma) {
		return false;
	}
	if (nome == null) {
		if (other.nome != null) {
			return false;
		}
	} else if (!nome.equals(other.nome)) {
		return false;
	}
	return true;
}

}
[/code]

[code]@SuppressWarnings("serial")
@Entity
@Table(name = "prt_faleconosco")
@SequenceGenerator(name = "seqPrtFaleConosco", sequenceName = "seq_prt_faleconosco", allocationSize = 1)
public class FaleConosco implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqPrtFaleConosco")
@Column(nullable = false)
private Integer idFaleConosco;

@Column(nullable = false, length = 50)
private String nome;

@Column(nullable = false, length = 50)
private String email;

@Column(nullable = false, length = 5)
private String dddTelefone;

@Column(nullable = false, length = 8)
private String numeroTelefone;

@Column(nullable = false, length = 1000)
private String mensagem;

@Column(nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date dataHora;

@Column(nullable = false, length = 50)
private String assunto;

@ManyToOne(optional = false)
@JoinColumn(name = "idcontato")
private Contato contato;

@Version
private Integer optlock;

public Integer getIdFaleConosco() {
	return idFaleConosco;
}

public void setIdFaleConosco(Integer idFaleConosco) {
	this.idFaleConosco = idFaleConosco;
}

public String getNome() {
	return nome;
}

public void setNome(String nome) {
	this.nome = nome;
}

public String getEmail() {
	return email;
}

public void setEmail(String email) {
	this.email = email;
}

public String getDddTelefone() {
	return dddTelefone;
}

public void setDddTelefone(String dddTelefone) {
	this.dddTelefone = dddTelefone;
}

public String getNumeroTelefone() {
	return numeroTelefone;
}

public void setNumeroTelefone(String numeroTelefone) {
	this.numeroTelefone = numeroTelefone;
}

public String getMensagem() {
	return mensagem;
}

public void setMensagem(String mensagem) {
	this.mensagem = mensagem;
}

public Date getDataHora() {
	return dataHora;
}

public void setDataHora(Date dataHora) {
	this.dataHora = dataHora;
}

public String getAssunto() {
	return assunto;
}

public void setAssunto(String assunto) {
	this.assunto = assunto;
}

public Contato getContato() {
	return contato;
}

public void setContato(Contato contato) {
	this.contato = contato;
}

public Integer getOptlock() {
	return optlock;
}

public void setOptlock(Integer optlock) {
	this.optlock = optlock;
}

@Override
public int hashCode() {
	final int prime = 31;
	int result = 1;
	result = prime * result + ((dataHora == null) ? 0 : dataHora.hashCode());
	result = prime * result + ((idFaleConosco == null) ? 0 : idFaleConosco.hashCode());
	return result;
}

@Override
public boolean equals(Object obj) {
	if (this == obj) {
		return true;
	}
	if (obj == null) {
		return false;
	}
	if (!(obj instanceof FaleConosco)) {
		return false;
	}
	FaleConosco other = (FaleConosco) obj;
	if (dataHora == null) {
		if (other.dataHora != null) {
			return false;
		}
	} else if (!dataHora.equals(other.dataHora)) {
		return false;
	}
	if (idFaleConosco == null) {
		if (other.idFaleConosco != null) {
			return false;
		}
	} else if (!idFaleConosco.equals(other.idFaleConosco)) {
		return false;
	}
	return true;
}

}
[/code]

O problema ocorre ao tentar remover um registro de Contato, segue o método no EJB:

[code] public void remove(Integer id) {
Contato contato = em.find(Contato.class, id);

	if (contato == null) {
		throw new BusinessException("Registro inexistente", "erroRegistroInexistente");
	}

	if (!contato.getFaleConoscos().isEmpty()) {
		throw new BusinessException("Existem registros de fale conosco vinculados ao contato",
				"erroContatoComFaleConosco");
	}

	em.remove(contato);
}[/code]

É feita uma verificação, se houverem registros de FaleConosco vinculados ao Contato, então é lançada exceção não permitindo a remoção, até aí tudo bem.

Foi cadastrado um registro de contato e um de fale conosco vinculado a esse contato, só que quando a linha "contato.getFaleConoscos().isEmpty()" é executada, ela retorna true, como se não tivessem registros vinculados ao contato, o que na verdade está errado, existe registro vinculado.

Após a execução dessa verificação, é executado o "em.remove(contato)", aí outro problema ocorre, o método fica travado e não dá mais retorno, chega até a colocar no log a execução do seguinte sql:

DELETE FROM prt_contato WHERE ((IDCONTATO = ?) AND (OPTLOCK = ?)) bind => [13, 1]

e fica preso aí…

Dúvidas:

1 - Por que quando é executada "contato.getFaleConoscos().isEmpty()" a lista está vindo vazia, sendo que existem registros associados ao contato?

2 - Por que a execução fica travada? (parece que ocorre algo como a abertura de uma transação e a mesma ficando aberta sem efetuar commit)

Sugestões?

É usado JPA 1.0 com implementação do toplink rodando num glassfish 2.1.

PS: Existe outro relacionamento semelhante aqui entre outras classes e funciona perfeitamente, no caso do "remove" é feita a mesma verificação e funciona…