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

Boa Tarde Pessoal,

Eu tenho a seguinte estrutura de classe:

[code]@MappedSuperclass
public class Persistivel {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;

 // Getters & Setters

}[/code]

[code]@Entity
@Table(name=“tipo_ganho”, schema=“public”)
public class TipoGanho extends Persistivel implements Jsonable {

 @Column(length=100)
 private String nome;

 // Getters & Setters

}[/code]

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

}[/code]
Converter:[code]@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 &quot;data&quot;
  String json = &quot;{\&quot;data\&quot;:&quot;+ value +&quot;}&quot;;
  
  XStream xstream = new XStream(new JettisonMappedXmlDriver());
  
  // Registrando os converters
  xstream.registerConverter(new LongConverter());
  xstream.registerConverter(new DateConverter());
  
  // Ajustando a estrutura do XML
  xstream.alias(&quot;data&quot;, type);
  
  // Convertendo o XML em Object
  return (Jsonable) xstream.fromXML(json);

}
}[/code]
Controller:[code]
@Resource
public class GanhoController {
// …

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


@Post
@Path(&quot;/ganho/controleGanho/insert.json&quot;)
@Restrito
@Transactional
public void controleGanhoInsert(ControleGanho data) {
    // .......
}

// ...

}
[/code]
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 {&quot;id&quot;:&quot;&quot;,&quot;nome&quot;:&quot;Tipo de Ganho Teste&quot;} dir ASC limit limit sort id start start total totalO 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 {&quot;id&quot;:&quot;&quot;,&quot;valor&quot;:1,&quot;data&quot;:&quot;2011-10-01T00:00:00&quot;,&quot;tipoGanho&quot;:6} dir ASC limit limit sort data start start total totalEle 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:

ele dá algum erro?

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:

mas aqui:

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

nem o id nem o nome estao preenchidos :wink:

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…

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