2010-06-05 2 views
1

Je n'arrive pas à essayer de conserver une entité dont l'ID est une valeur générée. Cette entité (A), au moment de la persistance, doit persister en cascade d'une autre entité (B). La relation entre A et B est OneToMany et la propriété liée à B fait partie d'une clé composite.Impossible de synchroniser l'état de la base de données avec la session

J'utilise Eclipse, JBOSS Runtime, JPA/Hibernate

Voici mon code:

Entité A:

@Entity 
public class Cambios implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @SequenceGenerator(name="CAMBIOS_GEN",sequenceName="CAMBIOS_SEQ",allocationSize=1) 
    @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="CAMBIOS_GEN") 
    @Column(name="ID_CAMBIO") 
    private Long idCambio; 

    //bi-directional many-to-one association to ObjetosCambio 
    @OneToMany(cascade={CascadeType.PERSIST},mappedBy="cambios") 
    private List<ObjetosCambio> objetosCambioList; 

    public Cambios() { 
    } 

    ... 
} 

Entité B:

@Entity 
@Table(name="OBJETOS_CAMBIO") 
public class ObjetosCambio implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @EmbeddedId 
    private ObjetosCambioPK id; 

    //bi-directional many-to-one association to Cambios 
    @ManyToOne 
    @JoinColumn(name="ID_CAMBIO", insertable=false, updatable=false) 
    private Cambios cambios; 

    //bi-directional many-to-one association to Objetos 
    @ManyToOne 
    @JoinColumn(name="ID_OBJETO", insertable=false, updatable=false) 
    private Objetos objetos; 

    public ObjetosCambio() { 
    } 

... 

Entité B PK:

@Embeddable 
public class ObjetosCambioPK implements Serializable { 
    //default serial version id, required for serializable classes. 
    private static final long serialVersionUID = 1L; 

    @Column(name="ID_OBJETO") 
    private Long idObjeto; 

    @Column(name="ID_CAMBIO") 
    private Long idCambio; 

    public ObjetosCambioPK() { 
    } 

Client:

public String generarCambio(){ 

     ServiceLocator serviceLocator = null; 
     try {   
      serviceLocator = serviceLocator.getInstance(); 
      FachadaLocal tcLocal; 
      tcLocal = (FachadaLocal)serviceLocator.getFacadeService("java:comp/env/negocio/Fachada"); 

      Cambios cambio = new Cambios(); 

      Iterator it = objetosLocal.iterator(); //OBJETOSLOCAL IS ALREADY POPULATED OUTSIDE OF THIS METHOD    
      List<ObjetosCambio> ocList = new ArrayList();    
      while (it.hasNext()){ 
        Objetos objeto = (Objetos)it.next(); 
        ObjetosCambio objetosCambio = new ObjetosCambio(); 
        objetosCambio.setCambios(cambio); //AT THIS TIME THIS "CAMBIO" DOES NOT HAVE ITS ID, ITS SUPPOSED TO BE GENERATED AT PERSISTENCE TIME 

        ObjetosCambioPK ocPK = new ObjetosCambioPK(); 
        ocPK.setIdObjeto(objeto.getIdObjeto()); 

        objetosCambio.setId(ocPK); 
        ocList.add(objetosCambio); 
           } 

      cambio.setObjetosCambioList(ocList); 

      tcLocal.persistEntity(cambio); 
      return "exito";    
       } catch (NamingException e) { 
        // TODO     
        e.printStackTrace();      
              } 
     return null; 
    } 


ERROR: 

15:23:25,717 WARN [JDBCExceptionReporter] SQL Error: 1400, SQLState: 23000 
15:23:25,717 ERROR [JDBCExceptionReporter] ORA-01400: no se puede realizar una inserción NULL en ("CDC"."OBJETOS_CAMBIO"."ID_CAMBIO") 

15:23:25,717 WARN [JDBCExceptionReporter] SQL Error: 1400, SQLState: 23000 
15:23:25,717 ERROR [JDBCExceptionReporter] ORA-01400: no se puede realizar una inserción NULL en ("CDC"."OBJETOS_CAMBIO"."ID_CAMBIO") 

15:23:25,717 ERROR [AbstractFlushingEventListener] Could not synchronize database state with session 
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update 
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94) 
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) 
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167) 
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) 
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50) 
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027) 
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365) 
    at org.hibernate.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:504) 
    at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:101) 
    at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:269) 
    at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:89) 
    at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:177) 
    at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1423) 
    at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:137) 
    at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:75) 
    at org.jboss.aspects.tx.TxPolicy.endTransaction(TxPolicy.java:170) 
    at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:87) 
    at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:190) 
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
    at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76) 
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
    at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42) 
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
    at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:186) 
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
    at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:41) 
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
    at org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:67) 
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
    at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67) 
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
    at org.jboss.ejb3.session.SessionSpecContainer.invoke(SessionSpecContainer.java:176) 
    at org.jboss.ejb3.session.SessionSpecContainer.invoke(SessionSpecContainer.java:216) 
    at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:207) 
    at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:164) 
    at $Proxy298.persistEntity(Unknown Source) 
    at backing.SolicitudCambio.generarCambio(SolicitudCambio.java:521) 
    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 com.sun.faces.el.MethodBindingImpl.invoke(MethodBindingImpl.java:146) 
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:92) 
    at javax.faces.component.UICommand.broadcast(UICommand.java:332) 
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:287) 
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:401) 
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:95) 
    at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:245) 
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:110) 
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:213) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:301) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) 
    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:235) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 
    at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190) 
    at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92) 
    at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126) 
    at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
    at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330) 
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829) 
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598) 
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) 
    at java.lang.Thread.run(Unknown Source) 
Caused by: java.sql.BatchUpdateException: ORA-01400: no se puede realizar una inserción NULL en ("CDC"."OBJETOS_CAMBIO"."ID_CAMBIO") 

Merci à l'avance! JM.-


J'ai essayé de mettre cambios.idCambio manuellement mais je me fais toujours la même erreur. Hibernate devrait faire une sorte de correspondance entre objetosCambioPK.idCambio et objetosCambio.cambios. Peut-être que c'est ce qui me manque ici, et je ne sais pas comment l'appliquer.

Quelqu'un?

Répondre

1

Je ne pense pas que le code ci-dessus peut fonctionner, le idCambio de votre ObjetosCambioPK intégrable n'est simplement jamais affecté, d'où l'erreur de base de données. En fait, je ne sais pas comment réaliser ce que vous voulez d'une manière "entièrement automatisée" (je ne pense pas que ce soit faisable) et je voudrais d'abord persist() et flush() le nouveau Cambios puis définir le Id affecté sur la clé composite de chaque instance ObjetosCambio.

+0

Merci pour votre réponse, je l'ai déjà fait une fois mais c'était avec une architecture différente (EJB3, Jdeveloper, Toplink), donc je sais que cela pourrait fonctionner. À l'époque, j'utilisais l'annotation '@ IdClass' au lieu de' @ EmbeddedId', mais j'ai lu que ce n'est pas la meilleure approche de nos jours, il semble que cette @IdClass n'a été implémentée que dans Hibernate à cause de la compatibilité EJB2. En plus de cela, j'ai des problèmes avec '@ idClass' aussi ... donc je préfère continuer à essayer de trouver une solution pour celle-ci. En ce qui concerne votre conseil: – Steppen

+0

"Je voudrais donc persister() et vider() le nouveau Cambios en premier, puis définir l'ID assigné sur la clé composite de chaque instance d'ObjetosCambio." Si je fais cela comme vous le dites, ne risquerais-je pas de laisser la base de données dans un état incohérent? (Dans le cas où une exception survient au temps de persistance 'ObjetosCambio') – Steppen

+0

@Steppen Si une exception survient à l'heure de persistance de' ObjetosCambio', la transaction sera annulée et vous ne serez pas dans un état incohérent. –

Questions connexes