2010-12-14 4 views
1

J'ai un problème avec une relation ManyToMany entre entités. Ajouter des travaux très bien mais je ne peux pas enlever une commune.problème avec une relation ManyToMany entre entités

Voici mes ENTITES:

public class Tuteur implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    private String nom; 

    @ManyToMany(mappedBy="tuteurs",fetch=FetchType.EAGER) 
    private List<Commune> communes; 
    ... 
} 


public class Commune implements Serializable { 
private static final long serialVersionUID = 1L; 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private Long id; 
private String nomCommune; 


@ManyToMany(fetch=FetchType.EAGER) 
@JoinTable(name="Tuteur_Commune",[email protected](name="Commune_Fk", 
      referencedColumnName="id") 
        ,[email protected](name="Tuteur_Fk",referencedColumnName="id")) 
private List<Tuteur> tuteurs; 
...} 

J'ai ce message d'erreur:

javax.faces.el.EvaluationException: javax.ejb.EJBException: Transaction aborted 
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102) 
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) 
at javax.faces.component.UICommand.broadcast(UICommand.java:315) 
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:775) 
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1267) 
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82) 
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) 
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312) 
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188) 
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641) 
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97) 
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185) 
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226) 
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165) 
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791) 
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693) 
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954) 
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170) 
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135) 
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102) 
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88) 
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76) 
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53) 
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57) 
at com.sun.grizzly.ContextTask.run(ContextTask.java:69) 
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330) 
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309) 
at java.lang.Thread.run(Thread.java:636) 
Caused by: javax.ejb.EJBException: Transaction aborted 
at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5046) 
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4805) 
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2004) 
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1955) 
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:198) 
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:84) 
at $Proxy218.supprimer(Unknown Source) 
at SessionTest.__EJB31_Generated__TestSession__Intf____Bean__.supprimer(Unknown Source) 
at test.supprimer(test.java:66) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:616) 
at com.sun.el.parser.AstValue.invoke(AstValue.java:234) 
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297) 
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:98) 
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) 
... 32 more 
Caused by: javax.transaction.RollbackException: Transaction marked for rollback. 
at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:450) 
at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.commit(JavaEETransactionManagerSimplified.java:837) 
at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5040) 
... 48 more 
Caused by: Exception [EclipseLink-45] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.DescriptorException 
Exception Description: Missing mapping for field [Commune.id]. 
Descriptor: RelationalDescriptor(entites.Commune --> [DatabaseTable(Commune)]) 
at org.eclipse.persistence.exceptions.DescriptorException.missingMappingForField(DescriptorException.java:951) 
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.extractValueFromObjectForField(ObjectBuilder.java:1970) 
at org.eclipse.persistence.mappings.ManyToManyMapping.prepareTranslationRow(ManyToManyMapping.java:931) 
at org.eclipse.persistence.mappings.ManyToManyMapping.earlyPreDelete(ManyToManyMapping.java:135) 
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1374) 
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:547) 
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1508) 
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:3128) 
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:268) 
at org.eclipse.persistence.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:157) 
at org.eclipse.persistence.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:68) 
at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:412) 
... 50 more 
+0

Quand obtenez-vous l'exception? Que voulez-vous dire par "note rmeove Commune"? – Nick

+0

GRAVE: javax.ejb.EJBException: Transaction annulée et je ne peux pas supprimer Comune et – Kohan95

Répondre

2

Vous ne pouvez pas supprimer une commune quand il est lié à un ou plusieurs enregistrements TUTEUR en raison de clé étrangère contraintes. Vous devez utiliser l'une des options Cascade pour supprimer les enregistrements dépendants (bien que cela soit inhabituel pour les relations plusieurs-à-plusieurs comme dans votre cas), ou vous devez écrire une logique qui interrompt la relation.

Donc je suppose que dans votre cas, la solution correcte serait d'effacer d'abord la relation entre l'instance de Commune et toutes les instances de Tuteur référencées, puis de supprimer l'instance de Commune.

Vous pouvez le faire comme programme indiqué ci-dessous:

for (Tuteur tuteur in commune.tuteurs) { 
    tuteur.getCommunes().remove(commune); 
    entityManager.persist(tuteur); 
} 

commune.getTuteurs().clear(); 
entityManager.persist(commune); 
entityManager.remove(commune); 

Ou avec quelques déclarations de mise à jour JPQL.

Edit: Je relis votre trace de la pile, qui contient la cause fondamentale suivante:

Caused by: Exception [EclipseLink-45] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.DescriptorException 
Exception Description: Missing mapping for field [Commune.id]. 
Descriptor: RelationalDescriptor(entites.Commune --> [DatabaseTable(Commune)]) 

Maintenant, dans mon expérience EclipseLink parfois lancer des exceptions trompeuses ou prêtant à confusion.

J'ai regardé votre déclaration @JoinTable et j'ai remarqué que dans votre cas particulier, l'option referenceColumnName peut être omis, puisque votre clé étrangère est la colonne @Id de la table cible dans les deux sens. Je ne pense pas que ce soit la cause du problème, mais vous pourriez vouloir essayer de toute façon.

Une autre option à essayer consiste simplement à laisser JPA et EclipseLink définir la table de jointure. Vous faites cela en omettant complètement la déclaration @JoinTable. À moins que vous n'ayez une raison spécifique pour déclarer manuellement la table de jointure, c'est le chemin à parcourir quand même. Rappelez-vous que bon nombre des améliorations apportées à EJB 3.0 concernent le contrôle conventionnel afin de réduire le code et les exigences de configuration de la plaque de la chaudière.

+0

Que puis-je dire juste merci beaucoup, tout ce que j'ai fait était de supprimer @JoinTable et cela fonctionne très bien, merci encore – Kohan95

Questions connexes