2010-06-11 7 views
1

Je suis nouveau à Hibernate + Derby ... J'ai vu ce problème mentionné tout au long de la google, mais je n'ai pas vu une bonne résolution.derby + hibernate ConstraintViolationException utilisant manytomany relations

Ce code suivant fonctionne très bien avec MySQL, mais lorsque je tente ce derby sur i obtenir des exceptions:

(chaque balise a deux ensembles de fichiers et vice-versa - ManyToMany)

Tags.java

@Entity 
@Table(name="TAGS") 
public class Tags implements Serializable 
{ 

    @Id @GeneratedValue(strategy=GenerationType.AUTO) 
    public long getId() 
    { 
     return id; 
    } 

    @ManyToMany(targetEntity=Files.class 
    ) 
    @ForeignKey(name="USER_TAGS_FILES",inverseName="USER_FILES_TAGS") 
    @JoinTable(name="USERTAGS_FILES", 
     [email protected](name="TAGS_ID"), 
     [email protected](name="FILES_ID")) 
     public Set<data.Files> getUserFiles() 
     { 
     return userFiles; 
     } 

    @ManyToMany(mappedBy="autoTags", 
     targetEntity=data.Files.class) 
     public Set<data.Files> getAutoFiles() 
     { 
     return autoFiles; 
     } 

Files.java


@Entity 
@Table(name="FILES") 
public class Files implements Serializable 
{ 
    @Id @GeneratedValue(strategy=GenerationType.AUTO) 
    public long getId() 
    { 
     return id; 
    } 
     @ManyToMany(mappedBy="userFiles", 
     targetEntity=data.Tags.class) 
    public Set getUserTags() 
    { 
     return userTags; 
    } 
    @ManyToMany(targetEntity=Tags.class 
     ) 
     @ForeignKey(name="AUTO_FILES_TAGS",inverseName="AUTO_TAGS_FILES") 
    @JoinTable(name="AUTOTAGS_FILES", 
     [email protected](name="FILES_ID"), 
     [email protected](name="TAGS_ID")) 
    public Set getAutoTags() 
    { 
     return autoTags; 
    } 

-je ajouter des données à la DB, mais lors de l'exécution sur Derby ces exceptions se présentent (ne pas le mysql)

Exceptions


SEVERE: DELETE on table 'FILES' caused a violation of foreign key constraint 'USER_FILES_TAGS' for key (3). The statement has been rolled back. 
Jun 10, 2010 9:49:52 AM org.hibernate.event.def.AbstractFlushingEventListener performExecutions 
SEVERE: Could not synchronize database state with session 
org.hibernate.exception.ConstraintViolationException: could not delete: [data.Files#3] 
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96) 
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) 
    at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2712) 
    at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2895) 
    at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:97) 
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:260) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184) 
    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:1206) 
    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:613) 
    at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:344) 
    at $Proxy13.flush(Unknown Source) 
    at data.HibernateORM.removeFile(HibernateORM.java:285) 
    at data.DataImp.removeFile(DataImp.java:195) 
    at booting.DemoBootForTestUntilTestClassesExist.main(DemoBootForTestUntilTestClassesExist.java:62) 

Je ne l'ai jamais utilisé derby avant si peut-être il y a quelque chose de crutal que je manque
1) qu'est-ce que je fais mal?
2) existe-t-il un moyen de cascader correctement lorsque j'ai 2 relations plusieurs-à-plusieurs entre deux classes?

Merci!

+0

s'il vous plaît pouvez-vous poster votre code qui fait le removeFile – Ross

Répondre

1

Ce code suivant fonctionne très bien avec MySQL, mais lorsque je tente ce derby sur je reçois des exceptions:

Je pense que vous n'utilisez pas l'intégrité référentielle avec MySQL (et non le moteur InnoDB) donc la violation de contrainte n'a pas été "déclenchée". Mais l'erreur est là.

Et en fait, le problème est que vous devez mettre le mappedBy sur le même côté des associations bi-directionnelle, par exemple sur Tags pour les ManyToMany (et le retirer de Files):

@Entity 
public class Tags implements Serializable { 

    @ManyToMany(mappedBy = "userTags") 
    @ForeignKey(name = "USER_TAGS_FILES", inverseName = "USER_FILES_TAGS") 
    @JoinTable(name = "USERTAGS_FILES", joinColumns = @JoinColumn(name = "TAGS_ID"), inverseJoinColumns = @JoinColumn(name = "FILES_ID")) 
    public Set<Files> getUserFiles() { 
     return userFiles; 
    } 

    @ManyToMany(mappedBy = "autoTags") 
    public Set<Files> getAutoFiles() { 
     return autoFiles; 
    } 

    //... 
} 

Et Files devient:

@Entity 
public class Files implements Serializable { 

    @ManyToMany 
    public Set<Tags> getUserTags() { 
     return userTags; 
    } 

    @ManyToMany 
    @ForeignKey(name = "AUTO_FILES_TAGS", inverseName = "AUTO_TAGS_FILES") 
    @JoinTable(name = "AUTOTAGS_FILES", joinColumns = @JoinColumn(name = "FILES_ID"), inverseJoinColumns = @JoinColumn(name = "TAGS_ID")) 
    public Set<Tags> getAutoTags() { 
     return autoTags; 
    } 

    // ... 
} 

Avec ces changements, les passes de test suivantes (le session est créé en dehors de la méthode d'essai):

@Test 
public void removeFiles() { 
    Files files = (Files) session.get(Files.class, 1L); 

    session.delete(files); 
    session.flush(); 

    Query q = session.createQuery("from Files f where f.id = :id"); 
    q.setParameter("id", 1l); 
    Files result = (Files) q.uniqueResult(); 
    assertNull(result); 
} 

et génère les requêtes suivantes:

 
Hibernate: select files0_.id as id100_0_ from Files files0_ where files0_.id=? 
Hibernate: delete from AUTOTAGS_FILES where FILES_ID=? 
Hibernate: delete from Files_TAGS where userFiles_id=? 
Hibernate: delete from Files where id=? 
Hibernate: select files0_.id as id100_ from Files files0_ where files0_.id=? 

testé avec Derby.

+0

votre exemple n'a ajouté aucun tag à l'objet Files Si vous deviez ajouter le code suivant, je pense que vous auriez toujours l'excetpion (comme c'est pour moi) Tags tags = (Tags) session.get (Tags.class, 1L); tags.getUserFiles().Ajouter des fichiers); il devrait toujours générer la même exception – msshapira

+0

@ msshapira: 1. Fixer le mapping comme suggéré 2. Fournissez votre code comme demandé, je ne vous aiderai pas plus loin sans voir votre code (et mappages fixes). –

+0

Je l'ai corrigé d'une manière beaucoup plus simple, je ne savais pas que lors de la suppression avec manytomany je dois annuler les ensembles pour supprimer les contraintes. merci pour votre aide – msshapira

Questions connexes