VRaptor 3.4.0 + ExtJS 4 - Duvida sobre Json (Serialização de Entidades)

5 respostas
guivirtuoso

Boa Tarde Pessoal,

Eu tenho a seguinte estrutura de classe:
@MappedSuperclass
public class Persistivel {
    
     @Id
     @GeneratedValue(strategy=GenerationType.IDENTITY)
     private Long id;

     // Getters & Setters
}
@Entity
@Table(name="tipo_ganho", schema="public")
public class TipoGanho extends Persistivel implements Jsonable {
	
     @Column(length=100)
     private String nome;

     // Getters & Setters
}
@Entity
@Table(name="controle_ganho", schema="public")
public class ControleGanho extends Persistivel implements Jsonable {

     @Column(name="valor", precision=2)
     private Double valor;
    
     @Column(name="data", nullable=false)
     @Temporal(TemporalType.DATE)
     private Date data;
    
     @ManyToOne(fetch=FetchType.LAZY) 
     @JoinColumn(name="id_tipo_ganho")
     private TipoGanho tipoGanho;

     // Getters & Setters
}
Converter:
@Convert(Jsonable.class)
@ApplicationScoped
public class JsonableConverter implements Converter<Jsonable>{

   public Jsonable convert(String value, Class<? extends Jsonable> type, ResourceBundle bundle) {
      
       if (Strings.isNullOrEmpty(value)) {
          return null;
      }
      
      // Montando o json com o root "data"
      String json = "{\"data\":"+ value +"}";
      
      XStream xstream = new XStream(new JettisonMappedXmlDriver());
      
      // Registrando os converters
      xstream.registerConverter(new LongConverter());
      xstream.registerConverter(new DateConverter());
      
      // Ajustando a estrutura do XML
      xstream.alias("data", type);
      
      // Convertendo o XML em Object
      return (Jsonable) xstream.fromXML(json);
      
   }
}
Controller:
@Resource
public class GanhoController {
    // ...

    @Post
    @Path("/ganho/tipoGanho/insert.json")
    @Restrito
    @Transactional
    public void tipoGanhoInsert(TipoGanho data) {
            // ......
    }


    @Post
    @Path("/ganho/controleGanho/insert.json")
    @Restrito
    @Transactional
    public void controleGanhoInsert(ControleGanho data) {
        // .......
    }
 
    // ...
}
Com a estrutura acima está ocorrendo o seguinte: Quando o ExtJS envia para a controller o json para inserir um TipoGanho:
Parâmetrosapplication/x-www-form-urlencoded
data	{"id":"","nome":"Tipo de Ganho Teste"}
dir	ASC
limit	limit
sort	id
start	start
total	total
O Converter cria o objeto certinho... e o insert é realizado com sucesso. Quando o ExtJS envia para a controller o json para inserir um ControleGanho:
Parâmetrosapplication/x-www-form-urlencoded
data	{"id":"","valor":1,"data":"2011-10-01T00:00:00","tipoGanho":6}
dir	ASC
limit	limit
sort	data
start	start
total	total
Ele não está conseguindo criar o Objeto TipoGanho para alimentar o atributo do ControleGanho.

Já li muitos Posts com problemas relacionados, mas são todos Posts antigos.. .2009, 2010 e de lá para cá o VRaptor já mudou bastante na questão de Serialização/Deserialização de Jsons.

E portanto gostaria de ajuda para saber como faço p/ que no segundo caso, eu consiga alimentar o atributo tipoGanho da Entity ControleGanho.

Vlw pessoal. :wink:

5 Respostas

Lucas_Cavalcanti

ele dá algum erro?

guivirtuoso

Boa Noite Lucas,

Ele não dá erro, ele (VRaptor) simplesmente monta o Objeto ControleGanho com um (new TipoGanho, (id e nome NULL) ) no atributo tipoGanho.
Ai o erro acaba estourando no Hibernate.

Strack completa:GRAVE: Servlet.service() for servlet [default] in context with path [] threw exception org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: br.com.virtuoso.prosaude.model.ganho.TipoGanho at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:243) at org.hibernate.type.EntityType.getIdentifier(EntityType.java:456) at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:265) at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:275) at org.hibernate.type.TypeHelper.findDirty(TypeHelper.java:295) at org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:3403) at org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEventListener.java:520) at org.hibernate.event.def.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:230) at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:154) at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219) at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383) at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133) at br.com.caelum.vraptor.util.hibernate.HibernateTransactionInterceptor.intercept(HibernateTransactionInterceptor.java:50) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.virtuoso.prosaude.interceptor.NoCacheInterceptor.intercept(NoCacheInterceptor.java:44) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44) at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92) at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58) at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 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:929) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:279) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)

Vlw pela atenção… :wink:

Lucas_Cavalcanti

mas aqui:

data    {"id":"","valor":1,"data":"2011-10-01T00:00:00","tipoGanho":6}

nem o id nem o nome estao preenchidos :wink:

guivirtuoso

Entao… eu já tava ligado nisso… to vendo aqui p tratar esse json p/ que ele fique tipo …

Mas tava pensando se não teria como eu fazer um Converter… ou algum outro recurso do tipo… p; que quando viesse um atributo p/ VRaptor serializar … e esse atributo fosse Jsonable (Interface que minnhas classes implementam) por exemplo… ai ele já instanciava com o id setado. Quando viessem qualquer outro tipo de classe … ele contia fazendo a serializacao como faz hj em dia…

Ou não é usual esse nivel de personalizacao de um Converter?

Vlw…

Lucas_Cavalcanti

mas como vc vai passar esse id, se não for pelo json?

Criado 28 de outubro de 2011
Ultima resposta 29 de out. de 2011
Respostas 5
Participantes 2