findByPk

9 respostas
fabiojpoli
Bom dia, estou querendo algo que aparentemente é simples, mas como iniciante em java, estou achando bem burocrático. - Exibir a descrição de um Tipo de usuário na lista de usuários por exemplo, onde esta lista de usuários possui somente o id do Tipo de Usuário Para isso, tentei criar na minha DAO abstrata um método genérico "findByPk", onde faço isso:
@Autowired
	public void setSessionFactory(SessionFactory sessionFactory) {
		hibernateTemplate = new HibernateTemplate(sessionFactory);
	}

public Object findByPk(Integer pk) throws HibernateException, InstantiationException, IllegalAccessException{
		setSessionFactory(SessionFactory.class.newInstance().openSession().getSessionFactory());
		Object record = hibernateTemplate.get(classModel, pk);
		return record;
	}
Faço uso dele na minha model de usuário:
public String getTipoUsuario() throws HibernateException, InstantiationException, IllegalAccessException {
		return ((TipoUsuario) new TipoUsuarioDAO().findByPk(idTipoUsuario)).getNome();
	}

Mas me retorna este erro: org.codehaus.jackson.map.JsonMappingException: org.hibernate.SessionFactory (through reference chain: java.util.HashMap["rows"]->java.util.ArrayList[0]->com.policenosistemas.model.Usuario["tipoUsuario"])

Obs: Estou trabalhando com Spring + Hibernate + Ext JS (comunicação via Ajax/JSON)

Obrigado!

9 Respostas

nel

Esse método:

public String getTipoUsuario() throws HibernateException, InstantiationException, IllegalAccessException {  
        return ((TipoUsuario) new TipoUsuarioDAO().findByPk(idTipoUsuario)).getNome();  
    }

De onde tu pega a variável idTipoUsuario ? Tu não está usando um POJO com um DAO dentro né ?
E está muito pouco detalhado o erro. E tens certeza que a pesquisa é por PK e não está correndo o risco de retornar uma lista?

Posta a exceção completa e um código mais completo também.
Obs: porque não deixo a cargo do seu container web ou AS gerenciar as sesões?

fabiojpoli
nel:
Esse método:
public String getTipoUsuario() throws HibernateException, InstantiationException, IllegalAccessException {  
        return ((TipoUsuario) new TipoUsuarioDAO().findByPk(idTipoUsuario)).getNome();  
    }

De onde tu pega a variável idTipoUsuario ? Tu não está usando um POJO com um DAO dentro né ?
E está muito pouco detalhado o erro. E tens certeza que a pesquisa é por PK e não está correndo o risco de retornar uma lista?

Posta a exceção completa e um código mais completo também. Obs: porque não deixo a cargo do seu container web ou AS gerenciar as sesões?
Obrigado pela resposta..
De onde tu pega a variável idTipoUsuario ? Tu não está usando um POJO com um DAO dentro né ?
Acho que sim :), mas quero primeiro fazer funcionar, depois seguir o padrão correto. Estou fazendo isso pois por exemplo.. eu deixando este método na model assim:
public int getTipoUsuario() {  
      return idTipoUsuario;  
   }
Ele retorna no json de dados exatamente o que eu quero:
...,"tipoUsuario":1}...
Ou seja, então teoricamente ao inves de eu retornar o "1" -idTipoUsuario nesse campo, fazer um findByPk e trazer o nome desse tipoUsuario ("Administrador"), parece fazer sentido.
Obs: porque não deixo a cargo do seu container web ou AS gerenciar as sesões?
Não entendi muito bem, mas acho que isso já está sendo feito.
E está muito pouco detalhado o erro. E tens certeza que a pesquisa é por PK e não está correndo o risco de retornar uma lista?

Posta a exceção completa e um código mais completo também.


Set 05, 2012 10:12:52 AM org.apache.catalina.core.StandardWrapperValve invoke
Grave: Servlet.service() for servlet [Teste] in context with path [/Teste] threw exception
org.codehaus.jackson.map.JsonMappingException: org.hibernate.SessionFactory (through reference chain: java.util.HashMap["rows"]->java.util.ArrayList[0]->com.policenosistemas.model.Usuario["tipoUsuario"])
at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:214)
at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:179)
at org.codehaus.jackson.map.ser.SerializerBase.wrapAndThrow(SerializerBase.java:80)
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:127)
at org.codehaus.jackson.map.ser.ContainerSerializers$IndexedListSerializer.serialize(ContainerSerializers.java:78)
at org.codehaus.jackson.map.ser.ContainerSerializers$IndexedListSerializer.serialize(ContainerSerializers.java:44)
at org.codehaus.jackson.map.ser.MapSerializer.serializeEntries(MapSerializer.java:131)
at org.codehaus.jackson.map.ser.MapSerializer.serialize(MapSerializer.java:74)
at org.codehaus.jackson.map.ser.MapSerializer.serialize(MapSerializer.java:19)
at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:260)
at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:212)
at org.codehaus.jackson.map.ObjectMapper.writeValue(ObjectMapper.java:694)
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.writeInternal(MappingJacksonHttpMessageConverter.java:145)
at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:181)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.writeWithMessageConverters(AnnotationMethodHandlerAdapter.java:933)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.handleResponseBody(AnnotationMethodHandlerAdapter.java:898)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.getModelAndView(AnnotationMethodHandlerAdapter.java:843)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:423)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:409)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.InstantiationException: org.hibernate.SessionFactory
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at com.policenosistemas.dao.AbstractDAO.findByPk(AbstractDAO.java:67)
at com.policenosistemas.model.Usuario.getTipoUsuario(Usuario.java:117)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.codehaus.jackson.map.ser.BeanPropertyWriter.get(BeanPropertyWriter.java:232)
at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:197)
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:122)
... 38 more

Usuario.java
/**
 * Modelo para a tabela "usuario".
 *
 * Fabio Jr. Policeno <[email removido]> 
 * 29/08/2012
 */

package com.policenosistemas.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.hibernate.HibernateException;

import com.policenosistemas.dao.TipoUsuarioDAO;

@JsonAutoDetect
@Entity
@Table(name = "usuario")
public class Usuario {

	@Id
	@GeneratedValue
	@Column(name = "id")
	private int id;

	@Column(name = "nome", nullable = false)
	private String nome;

	@Column(name = "data_nascimento", nullable = false)
	private String dataNascimento;

	@Column(name = "ativo", nullable = false)
	private int ativo;

	@Column(name = "observacao", nullable = false)
	private String observacao;

	@Column(name = "foto", nullable = false)
	private String foto;

	@Column(name = "id_tipo_usuario", nullable = false)
	private int idTipoUsuario;
	
	@Column(name = "id_genero", nullable = false)
	private int idGenero;
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getNome() {
		return nome;
	}

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

	public String getDataNascimento() {
		return dataNascimento;
	}

	public void setDataNascimento(String dataNascimento) {
		this.dataNascimento = dataNascimento;
	}

	public int getAtivo() {
		return ativo;
	}

	public void setAtivo(int ativo) {
		this.ativo = ativo;
	}

	public String getObservacao() {
		return observacao;
	}

	public void setObservacao(String observacao) {
		this.observacao = observacao;
	}

	public String getFoto() {
		return foto;
	}

	public void setFoto(String foto) {
		this.foto = foto;
	}
	
	public int getIdGenero() {
		return idGenero;
	}

	public int getIdTipoUsuario() {
		return idTipoUsuario;
	}
	
	public void setIdGenero(int idGenero) {
		this.idGenero = idGenero;
	}

	public void setIdTipoUsuario(int idTipoUsuario) {
		this.idTipoUsuario = idTipoUsuario;
	}
	
	public String getTipoUsuario() throws HibernateException, InstantiationException, IllegalAccessException {
		return ((TipoUsuario) new TipoUsuarioDAO().findByPk(idTipoUsuario)).getNome();
	}

	public int getGenero() {
		return idGenero;
	}
}
TipoUsuarioDAO.java
/**
 * DAO do modulo "TipoUsuario".
 *
 * Fabio Jr. Policeno <[email removido]> 
 * 29/08/2012
 */
package com.policenosistemas.dao;

import org.springframework.stereotype.Repository;

import com.policenosistemas.model.TipoUsuario;

@Repository
public class TipoUsuarioDAO extends AbstractDAO{
	public TipoUsuarioDAO() {
		super(TipoUsuario.class);
	}
}
AbstractDAO
package com.policenosistemas.dao;

import java.util.List;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.orm.hibernate3.HibernateTemplate;

public class AbstractDAO {
	protected HibernateTemplate hibernateTemplate;
	protected Class<?> classModel;
	protected DetachedCriteria criteria;
	private JSONArray jFilter;
	
	protected AbstractDAO(Class<?> classModel) {
		this.classModel = classModel;
	}
	
	@Autowired
	public void setSessionFactory(SessionFactory sessionFactory) {
		hibernateTemplate = new HibernateTemplate(sessionFactory);
	}
	
	...
	
	public Object findByPk(Integer pk) throws HibernateException, InstantiationException, IllegalAccessException{
		setSessionFactory(SessionFactory.class.newInstance().openSession().getSessionFactory());
		Object record = hibernateTemplate.get(classModel, pk);
		return record;
	}
....
}
fabiojpoli

Sim, segundo a doc, retorna uma instancia e não uma list: http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/orm/hibernate3/HibernateTemplate.html#get(java.lang.Class, java.io.Serializable)

nel

Parece que o seu problema está na conversão para JSON.
Faça sua entidade Usuário implementar Serializable e crie um construtor default para ela.

As entidades devem sempre implementar Serializable, pois a tendência é que essa informação trafegue entre camadas.
E o ideal é tu aplicar JSON a um VO e não diretamente a entidade. E o parser obriga a ter um construtor default no seu objeto, pois ele faz um “new” nele.

Veja se isso resolve. Caso o erro persista, comente a linha que faz o parser e tente apenas buscar o nome, como desejas.
Mas ainda aposto minhas fichas que o seu problema é o parser.

Não, se tu abre e fecha a sessão do hibernate em código, quer dizer que é você mesmo que está gerenciado isso. É igual transação, você simplesmente a usa, não codifica isso.

fabiojpoli
nel:
Parece que o seu problema está na conversão para JSON. Faça sua entidade Usuário implementar Serializable e crie um construtor default para ela.
Fiz apenas isso a principio, mas o mesmo erro persiste
@JsonAutoDetect
@Entity
@Table(name = "usuario")
public class Usuario implements Serializable{

	public Usuario() {
		
	}
...
@JsonAutoDetect
@Entity
@Table(name = "tipo_usuario")
public class TipoUsuario implements Serializable {
	
	public TipoUsuario() {
		
	}
...
E o ideal é tu aplicar JSON a um VO e não diretamente a entidade. E o parser obriga a ter um construtor default no seu objeto, pois ele faz um "new" nele.

Veja se isso resolve. Caso o erro persista, comente a linha que faz o parser e tente apenas buscar o nome, como desejas.
Mas ainda aposto minhas fichas que o seu problema é o parser.


Não entendi onde e oq fazer

Não, se tu abre e fecha a sessão do hibernate em código, quer dizer que é você mesmo que está gerenciado isso. É igual transação, você simplesmente a usa, não codifica isso.
No findByPk faço isso.. mas no CRUD nao..
@Autowired
	public void setSessionFactory(SessionFactory sessionFactory) {
		hibernateTemplate = new HibernateTemplate(sessionFactory);
	}
nel

Esquece a discussão sobre gerenciamento do seu AS, não vem ao caso. Na verdade, esse tipo de tópico deveria estar no JEE.
Mas enfim, não resolveu? Estranho. Era exatamente aquilo para ser feito. De qualquer forma, precisa implementar Serializable e ter um construtor default.

Onde e como você está fazendo o parser? Podes postar o código? E o erro, é exatamente o mesmo?
O que eu disse para confirmar a exceção, é comentar o código que faz o parser, algo bem simples, só para testar se o teu find está correto. Algo como:

String nome = findByPk....; System.out.println("nome: " + nome);

Se trouxer o nome correto sem exceção, tu tem certeza que o teu problema está em gerar o JSON, entende?

fabiojpoli

nel:
Esquece a discussão sobre gerenciamento do seu AS, não vem ao caso. Na verdade, esse tipo de tópico deveria estar no JEE.
Mas enfim, não resolveu? Estranho. Era exatamente aquilo para ser feito. De qualquer forma, precisa implementar Serializable e ter um construtor default.

Onde e como você está fazendo o parser? Podes postar o código? E o erro, é exatamente o mesmo?
O que eu disse para confirmar a exceção, é comentar o código que faz o parser, algo bem simples, só para testar se o teu find está correto. Algo como:

String nome = findByPk....; System.out.println("nome: " + nome);

Se trouxer o nome correto sem exceção, tu tem certeza que o teu problema está em gerar o JSON, entende?


Postei todo meu código acima…sim o erro é exatamente o mesmo… entenda q o erro está dentro do metodo findByPk, entao nao conseguiria executar essas linhas q tu postou… o erro ocorre aqui:

setSessionFactory(SessionFactory.class.newInstance().openSession().getSessionFactory());

public Object findByPk(Integer pk) throws HibernateException, InstantiationException, IllegalAccessException{ setSessionFactory(SessionFactory.class.newInstance().openSession().getSessionFactory()); Object record = hibernateTemplate.get(classModel, pk); return record; }

nel

Provavelmente é como você está iniciando seu SessionFactory. Você conseguiu iniciar ele assim em outro local?
Ao que eu vi , precisa usar a classe Configuration do Hibernate no Hibernate 4, usa-se ServiceRegistry.

Dê uma olhada aqui: http://blog.caelum.com.br/as-novidades-do-hibernate-4/

Agora que eu percebi que tu usa o .class() diretamente. Assim deixa de carregar n informações.

fabiojpoli
nel:
Provavelmente é como você está iniciando seu SessionFactory. Você conseguiu iniciar ele assim em outro local? Ao que eu vi , precisa usar a classe Configuration do Hibernate no Hibernate 4, usa-se ServiceRegistry.

Dê uma olhada aqui: [url]http://blog.caelum.com.br/as-novidades-do-hibernate-4/[/url]

Agora que eu percebi que tu usa o .class() diretamente. Assim deixa de carregar n informações.
Bom, resolvi trabalhar da forma correta, com associations e funcionou agora com o if que coloquei com a ajuda do pessoal do javafree. De qualquer forma muito obrigado!
/**
 * Modelo para a tabela "usuario".
 *
 * Fabio Jr. Policeno <[email removido]> 
 * 29/08/2012
 */

package com.policenosistemas.model;

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

import org.codehaus.jackson.annotate.JsonAutoDetect;

@JsonAutoDetect
@Entity
@Table(name = "usuario")
public class Usuario {

	@Id
	@GeneratedValue
	@Column(name = "id")
	private int id;

	@Column(name = "nome", nullable = false)
	private String nome;

	@Column(name = "data_nascimento", nullable = false)
	private String dataNascimento;

	@Column(name = "ativo", nullable = false)
	private int ativo;

	@Column(name = "observacao", nullable = false)
	private String observacao;

	@Column(name = "foto", nullable = false)
	private String foto;

	@Column(name = "id_tipo_usuario", nullable = false)
	private int idTipoUsuario;
	
	@Column(name = "id_genero", nullable = false)
	private int idGenero;
	
	@ManyToOne
    @JoinColumn(name="id_tipo_usuario", insertable = false, updatable = false)
	private TipoUsuario tipoUsuario;
	
	@ManyToOne
    @JoinColumn(name="id_genero", insertable = false, updatable = false)
	private Genero genero;
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getNome() {
		return nome;
	}

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

	public String getDataNascimento() {
		return dataNascimento;
	}

	public void setDataNascimento(String dataNascimento) {
		this.dataNascimento = dataNascimento;
	}

	public int getAtivo() {
		return ativo;
	}

	public void setAtivo(int ativo) {
		this.ativo = ativo;
	}

	public String getObservacao() {
		return observacao;
	}

	public void setObservacao(String observacao) {
		this.observacao = observacao;
	}

	public String getFoto() {
		return foto;
	}

	public void setFoto(String foto) {
		this.foto = foto;
	}
	
	public int getIdGenero() {
		return idGenero;
	}

	public int getIdTipoUsuario() {
		return idTipoUsuario;
	}
	
	public void setIdGenero(int idGenero) {
		this.idGenero = idGenero;
	}

	public void setIdTipoUsuario(int idTipoUsuario) {
		this.idTipoUsuario = idTipoUsuario;
	}
	
	public String getTipoUsuario() {
		if (tipoUsuario != null) {
			return tipoUsuario.getNome();
		}
		return null;
	}

	public String getGenero() {
		if (genero != null) {
			return genero.getNome();
		}
		return null;  
	}
}
Criado 5 de setembro de 2012
Ultima resposta 5 de set. de 2012
Respostas 9
Participantes 2