JPA + Hibernate

Bom dia a todos,

Estou trabalhando no desenvolvimento de uma aplicação utilizando o Hibernate
com o JPA, mas quando eu efetuo uma consulta com o Log4j habilitado e para
imprimir a consulta, o select imprimi duas vezes a mesma consulta será que alguém
teria alguma suspeita do que pode estar causando isso.

Obrigado pela ajuda

Que método você usa? Que select ele faz duas vezes?

Depende muito… por exemplo, saveOrUpdate, merge, persist, depende o que você faz…

Eu utilizo o método

find(Class c , Object id)

que pertence a especificação do JPA.

Aqui funciona normal e mostra apenas um select no log4j :

// imports omitidos
public class pessoaTest {

	@Test
	public void consultaPessoa() {
		EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa-hibernate");
		EntityManager em = emf.createEntityManager();

		Pessoa retornoBusca = em.find(Pessoa.class, 2L);
		System.out.println("ID : " + retornoBusca.getId());
		System.out.println("Nome : " + retornoBusca.getNome());
		for ( Endereco mostraEndereco : retornoBusca.getEnderecoCollection() ) {
			System.out.println("Endereco " + mostraEndereco.getNome());
			System.out.println("Numero " + mostraEndereco.getNumero());
		}
		
		em.close();
		emf.close();
	}

}

Log gerado :

Desculpa a falta de informação na pergunta, refiz o teste e realmente quando eu executo um find só retorna apenas uma linha, mas retorna várias quando eu executo, está aqui.


EntityManagerFactory emf = Persistence.createEntityManagerFactory(JPAResourceHibernate.PERSISTENCE_UNIT_METRO_RIO_HIBERNATE);
EntityManager em = emf.createEntityManager();

		
Estacao estacao = (Estacao) em.createQuery("from Estacao").getResultList().get(0);
		
logger.trace("ID : " + estacao.getIdEstacao() + " - Estação :"
	+ estacao.getDescricaoEstacao());
		
em.close();
emf.close();

O métodos getResultList() retorna uma lista de resultados (vários).

Com isso eu concordo, ela retorna uma lista de objetos .

Um exemplo ela pode retornar uma lista de objetos pessoa, mas isso não quer dizer que está certo ela efetuar a mesma consulta inumeras vezes. E a mesma coisa que eu afirmar que isto está correto.

select * from pessoa
select * from pessoa
select * from pessoa
select * from pessoa

Para retornar uma única lista de Pessoa.

Ou será, que me conceito está errado. Acredito que eu esteja mapeando alguma coisa errada.

Fiz aqui na minha classe :

Pessoa pessoas = (Pessoa) em.createQuery("from Pessoa").getResultList().get(0); 

e no meu log ele gera apenas um select.

Veja o exemplo de como estão minhas classes :

Pessoa.java

package br.com.anderson.modelo;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "pessoa")
public class Pessoa implements Serializable{

	private static final long serialVersionUID = 1L;

	@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id", nullable = false)
	private Long id;
	
	@Column(name = "nome", nullable = false, length=50)
	private String nome;
	
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "idPessoa")
    private Set<Endereco> enderecoCollection = new HashSet<Endereco>();

	public Pessoa() {
	}
	
	public String getNome() {
		return nome;
	}

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

	public Long getId() {
		return id;
	}
	
	public Set<Endereco> getEnderecoCollection() {
		return enderecoCollection;
	}

}

Endereco.java

package br.com.anderson.modelo;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "endereco")
public class Endereco implements Serializable {

	private static final long serialVersionUID = 1L;

	@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name="id", nullable=false)
	private Long id;
	
	@Column(name="nome", nullable=false, length=50)
	private String nome;
	
	@Column(name="numero", nullable=false, length=10)
	private String numero;
	
    @JoinColumn(name = "idPessoa", referencedColumnName = "id")
    @ManyToOne
    private Pessoa idPessoa;
	
	public String getNome() {
		return nome;
	}

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

	public String getNumero() {
		return numero;
	}

	public void setNumero(String numero) {
		this.numero = numero;
	}

	public Long getId() {
		return id;
	}
	
	public Endereco() {
	}

    public Pessoa getIdPessoa() {
        return idPessoa;
    }

    public void setIdPessoa(Pessoa idPessoa) {
        this.idPessoa = idPessoa;
    }

}

Que tal o getSingleResult()?