findByPk

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:

[code]@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;
}[/code]

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!

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?

[quote=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?[/quote]
Obrigado pela resposta…

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.

Não entendi muito bem, mas acho que isso já está sendo feito.

[quote]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.[/quote]

[quote]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[/quote]

Usuario.java

[code]/**

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;
}

}[/code]

TipoUsuarioDAO.java

[code]/**

  • DAO do modulo “TipoUsuario”.
  • Fabio Jr. Policeno fabiojpoli@hotmail.com
  • 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);
}
}[/code]

AbstractDAO

[code]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;
}


}
[/code]

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)

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.

[quote=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.[/quote]
Fiz apenas isso a principio, mas o mesmo erro persiste

[code]@JsonAutoDetect
@Entity
@Table(name = “usuario”)
public class Usuario implements Serializable{

public Usuario() {
	
}

…[/code]

@JsonAutoDetect
@Entity
@Table(name = "tipo_usuario")
public class TipoUsuario implements Serializable {
	
	public TipoUsuario() {
		
	}
...

Não entendi onde e oq fazer

No findByPk faço isso… mas no CRUD nao…

@Autowired public void setSessionFactory(SessionFactory sessionFactory) { hibernateTemplate = new HibernateTemplate(sessionFactory); }

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?

[quote=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?[/quote]
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; }

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.

[quote=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.[/quote]
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!

[code]/**

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;  
}

}[/code]