[RESOLVIDO] vRaptor - ao listar exibe mais de uma vez o mesmo objeto

12 respostas
tefo

Boa noite galera!

to com um probleminha aqui… decorrente da solução que achei anteriormente em outro tópico: http://www.guj.com.br/java/284940-erro-em-relacionamento

seguinte, o objeto Debito possui uma lista de objetos MeioDepositoOrigemDebito, e ao listar (mostrar na tela) cada objeto Debito, ele eh exibido a mesma quantidade de vezes que o numero de objetos na lista de MeioDepositoOrigemDebito!!

no banco existe apenas um registro de cada Debito… e na tela mostra desse jeito…

Alguém já teve este problema?

12 Respostas

tefo

soh pra complementar:

  • no banco nao existem registros duplicados
  • a duplicaçao ocorre ao recuperar a lista de debitos, ou seja, a partir do seguinte método o objeto Debito já eh retornado duplicado na lista:public List<Debito> listarPorCenario(Long id){ return this.session.createCriteria(Debito.class).add(Restrictions.eq("idCenario", id)).list(); }
    mas essa mesma estrutura do método eh usado para recuperar outras listas e nao duplica os outros objetos dessas listas…
Lucas_Cavalcanti

vc tem algum fetch=…EAGER nessa classe Debito?

tefo

Eai Lucas!

Cara, vou postar a minha classe Debito pra vc dar uma olhada:
@Entity
public class Debito extends Valor implements Serializable {
	
    @NotNull(message="A operaçao necessaria deve ser informada!")
    private Boolean operacaoNecessaria;
	
    @ManyToOne
    @NotNull(message="O meio de debito deve ser informado!")
    private MeioDebito meioDebito;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = false)
    @NotNull(message="O meio de deposito de origem do debito deve ser informado!")
    private List<MeioDepositoOrigemDebito> listaMeioDepositoOrigemDebito;

    private Boolean snEntrada;
    
    public Debito(){
    }

    //getters and setters

}
Tem um EAGER sim.. isso eh um problema?
Lucas_Cavalcanti

eh, pq ele vai fazer um join pra poder buscar esse cara…

algum motivo forte pra ter esse EAGER? em geral deixar cascade=ALL também é errado, eh isso mesmo que vc quer?

tefo

bem… vamos por partes…

  • o EAGER eh pra carregar a lista quando o Debito for carregado, certo? Se sim, entao nao preciso disso
  • o cascade=ALL precisa pq essa lista vai ser persistida no mesmo momento em que o Debito for persistido, e a lista sera excluida quando o Debito for excluido…

respondi a sua pergunta?

Lucas_Cavalcanti

tire o eager, e se vc precisa do cascade pra PERSIST, deixe soh o cascade pra PERSIST, e nao o ALL :wink:

tefo

mas o cascade PERSIST também vai excluir em cascata a lista de objetos MeioDepositoOrigemDebito?

Lucas_Cavalcanti

nao… soh vai fazer a operaçao em cascata pro persist… pra fazer pro remove tb vc faz:

@....(cascade={...PERSIST, ....REMOVE}...)
tefo

eu fiz como vc disse Lucas, tirei o EAGER e o cascade.ALL@OneToMany(cascade = {CascadeType.PERSIST,CascadeType.REMOVE}, orphanRemoval = false) @NotNull(message="O meio de deposito de origem do debito deve ser informado!") private List<MeioDepositoOrigemDebito> listaMeioDepositoOrigemDebito;
mas deu esse erro agora:19/10/2012 18:30:05 org.apache.catalina.core.StandardWrapperValve invoke GRAVE: Servlet.service() for servlet default threw exception br.com.caelum.vraptor.InterceptionException: exception raised, check root cause for details: org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: br.com.website.bean.MeioDepositoOrigemDebito; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: br.com.website.bean.MeioDepositoOrigemDebito at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:96) 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.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:61) 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.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.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:87) at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59) 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:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:680) Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: br.com.website.bean.MeioDepositoOrigemDebito; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: br.com.website.bean.MeioDepositoOrigemDebito at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:654) at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793) at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723) at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) at $Proxy55.incluir(Unknown Source) at br.com.website.controller.DebitoController.incluir(DebitoController.java:145) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:61) ... 43 more Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: br.com.website.bean.MeioDepositoOrigemDebito at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:243) at org.hibernate.type.EntityType.getIdentifier(EntityType.java:456) at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:121) at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:815) at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1203) at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:58) at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:188) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) 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 org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656) ... 56 more

nunca vi esse erro antes…

Lucas_Cavalcanti

se vc deu save no Debito e ele tem cascade persist, nao deveria acontecer isso…

esse @OneToMany sem mappedBy eh de propósito?

tefo

Precisa do mappedBy?
Esse seria o motivo do erro?

tefo

Lucas, eu fiz assim e funcionou certinho:@OneToMany(cascade = CascadeType.ALL, orphanRemoval = false) @NotNull(message="O meio de deposito de origem do debito deve ser informado!") private List<MeioDepositoOrigemDebito> listaMeioDepositoOrigemDebito;

apenas substitui o cascade = {CascadeType.PERSIST,CascadeType.REMOVE} por cascade = CascadeType.ALL

estranho neh?!

Criado 18 de outubro de 2012
Ultima resposta 20 de out. de 2012
Respostas 12
Participantes 2