2011-05-17 1 views
7

J'essaie d'utiliser une carte comme type pour l'une de mes propriétés de modèle. Prenons ces deux classes par exemple:Utiliser Map comme propriété du modèle dans Play

@Entity 
public class Foo extends Model { 

    @OneToMany(mappedBy = "foo", cascade = CascadeType.ALL) 
    @MapKey(name = "name") 
    public Map<String, Bar> bars; 

    public String name; 

} 

@Entity 
public class Bar extends Model { 

    @ManyToOne 
    public Foo foo; 

    public String name; 
} 

Très simplifié bien sûr, mais c'est l'idée de base. Donc, ce que j'essaie de faire est d'obtenir une carte avec des valeurs comme barres et les noms comme leurs clés dans Foo.

Maintenant, je veux utiliser Fixture pour charger des données de ce fichier YAML:

Foo(foo1): 
    name: Foo1 

Foo(foo2): 
    name: Foo2 

Bar(bar1): 
    name: Bar1 
    foo: foo1 

Bar(bar2): 
    name: Bar2 
    foo: foo1 

Pas de problème jusqu'à présent, cela fonctionne comme un charme. Maintenant, si je tente de changer bar2 à foo: foo2, je reçois cette exception:

play.exceptions.JavaExecutionException: Cannot load fixture initial-data.yml: org.hibernate.HibernateException: Found two representations of same collection: models.Foo.bars 
    at play.jobs.Job.call(Job.java:166) 
    at Invocation.Job(Play!) 
Caused by: java.lang.RuntimeException: Cannot load fixture initial-data.yml: org.hibernate.HibernateException: Found two representations of same collection: models.Foo.bars 
    at play.test.Fixtures.loadModels(Fixtures.java:221) 
    at jobs.Bootstrap.doJob(Bootstrap.java:18) 
    at play.jobs.Job.doJobWithResult(Job.java:55) 
    at play.jobs.Job.call(Job.java:157) 
    ... 1 more 
Caused by: javax.persistence.PersistenceException: org.hibernate.HibernateException: Found two representations of same collection: models.Foo.bars 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1214) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1147) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1153) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:798) 
    at play.db.jpa.JPABase._save(JPABase.java:47) 
    at play.test.Fixtures.loadModels(Fixtures.java:205) 
    ... 4 more 
Caused by: org.hibernate.HibernateException: Found two representations of same collection: models.Foo.bars 
    at org.hibernate.engine.Collections.processReachableCollection(Collections.java:175) 
    at org.hibernate.event.def.FlushVisitor.processCollection(FlushVisitor.java:60) 
    at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:122) 
    at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:83) 
    at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:77) 
    at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:165) 
    at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:240) 
    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.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:795) 
    ... 6 more  

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.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:795) 
... 6 more 

Bien sûr, j'essayé de google mais n'a pas pu trouver une solution pour mon cas. Des idées là-dessus? Curieusement, je peux aller et changer les valeurs dans la base de données et ensuite attribuer bar2 à foo1 et tout fonctionne parfaitement bien, donc je ne peux pas être trop mal ...

aide serait appréciée :)

Best, kalarzo

+0

Vous pouvez essayer de poster cette question pour jouer à google group framework sur http://groups.google.com/group/play-framework, ils sont très réactifs ... – opensas

+0

J'ai posé cette question "très similaire" - identique [ ici] (http://stackoverflow.com/questions/8508068/how-to-debug-found-two-representations-of-same-collection). Découvrez [ce qui a fonctionné pour moi] (http://stackoverflow.com/a/8521408/11236). – ripper234

Répondre

-1

Retirez le:

@MapKey(name = "name") 
+0

Je suppose que l'utilisateur l'a mis là exprès. – pottedmeat

2

Je tryed votre code aujourd'hui et cela a fonctionné sans problèmes. Quelle version de jeu utilisez-vous? J'utilise 1.2.3.

Peut-être que le plugin association résout ce problème, car c'est ce que j'utilise en arrière-plan. S'il vous plaît laissez-moi savoir si une mise à niveau vous a aidé.

suit la procédure d'installation du module de lecture standard:

play install associations 

Ajoutez la ligne suivante à votre dependencies.yml remplaçant 1.0 avec la version souhaitée:

require: 
    - play -> associations 1.0 
0

J'ai eu le même problème dans v1. 2.3 avec des appareils. Curieusement, si je ne définissais pas un appareil en dessous de celui avec la relation bidirectionnelle Map OneToMany, il n'y avait pas de problème. J'ai également eu un problème avec l'un de mes contrôleurs si je n'avais pas complètement configuré la relation bidirectionnelle. Cela semble être directement lié à l'utilisation d'une carte dans une relation OneToMany bidirectionnelle. Je suis passé à un Set et le problème est parti. À la fin, j'ai réussi à résoudre la situation sans revenir à un ensemble en mettant à niveau vers v1.2.4RC2. J'ai jeté un rapide coup d'œil à la liste des changements dans v1.2.4RC2 mais je n'ai pas pu repérer quelque chose qui mentionnait directement la résolution de ce problème, mais quelque chose doit avoir été résolu.

Questions connexes