2010-03-22 9 views
5

Nous sommes nouveaux à JPA et essayons de mettre en place une relation un à plusieurs très simple où un pojo appelé Message peut avoir une liste d'ID de groupe entier définie par un joindre la table appelée GROUP_ASSOC. Voici le DDL:Le type de champ n'est pas supporté par la stratégie de persistance déclarée "OneToMany"

CREATE TABLE "APP"."MESSAGE" (
     "MESSAGE_ID" INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1) 
    ); 

ALTER TABLE "APP"."MESSAGE" ADD CONSTRAINT "MESSAGE_PK" PRIMARY KEY ("MESSAGE_ID"); 

CREATE TABLE "APP"."GROUP_ASSOC" (
     "GROUP_ID" INTEGER NOT NULL, 
     "MESSAGE_ID" INTEGER NOT NULL 
    ); 

ALTER TABLE "APP"."GROUP_ASSOC" ADD CONSTRAINT "GROUP_ASSOC_PK" PRIMARY KEY ("MESSAGE_ID", "GROUP_ID"); 

ALTER TABLE "APP"."GROUP_ASSOC" ADD CONSTRAINT "GROUP_ASSOC_FK" FOREIGN KEY ("MESSAGE_ID") 
    REFERENCES "APP"."MESSAGE" ("MESSAGE_ID");

Voici le POJO:

@Entity 
@Table(name = "MESSAGE") 
public class Message { 
    @Id 
    @Column(name = "MESSAGE_ID") 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int messageId; 

    @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST) 
    private List groupIds; 

    public int getMessageId() { 
     return messageId; 
    } 
    public void setMessageId(int messageId) { 
     this.messageId = messageId; 
    } 
    public List getGroupIds() { 
     return groupIds; 
    } 
    public void setGroupIds(List groupIds) { 
     this.groupIds = groupIds; 
    } 
}

Je sais que cela est faux car il n'y a pas de correspondance @Column-GROUP_ASSOC.GROUP_ID pour la propriété groupids, mais nous espérons que cela illustre ce que nous essayons faire. Lorsque nous exécutons le code de test suivant, nous obtenons <openjpa-1.2.3-SNAPSHOT-r422266:907835 fatal user error> org.apache.openjpa.util.MetaDataException: The type of field "pojo.Message.groupIds" isn't supported by declared persistence strategy "OneToMany". Please choose a different strategy.

Message msg = new Message(); 
List groups = new ArrayList(); 
groups.add(101); 
groups.add(102); 
EntityManager em = Persistence.createEntityManagerFactory("TestDBWeb").createEntityManager(); 
em.getTransaction().begin(); 
em.persist(msg); 
em.getTransaction().commit();

Aide!

Répondre

3

Lorsque vous travaillez avec JPA, vous devriez penser à l'objet et les relations entre les objets et vous devez mapper votre modèle objet, pas ids, à votre modèle relationnel (il est possible de tracer une List des valeurs de base avec @ElementCollection dans JPA 2.0 mais ce que j'ai dit juste avant s'applique toujours).

Ici, (en supposant que cela est vraiment un one-to-many relation entre Message et GroupAssoc et non un beaucoup à plusieurs relation entre Message et Group entités), vous devriez avoir quelque chose comme ceci:

@Entity 
@Table(name = "MESSAGE") 
public class Message implements Serializable { 
    @Id 
    @Column(name = "MESSAGE_ID") 
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    private Long messageId; 

    @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)  
    private List<GroupAssoc> groupAssocs = new ArrayList<GroupAssoc>(); 

    public Long getMessageId() { 
     return messageId; 
    } 
    public void setMessageId(Long messageId) { 
     this.messageId = messageId; 
    } 

    public List<GroupAssoc> getGroupAssocs() { 
     return groupAssocs; 
    } 
    public void setGroupAssocs(List<GroupAssoc> groupAssocs) { 
     this.groupAssocs = groupAssocs; 
    } 

    // equals() and hashCode() 
} 

Et une autre entité pour GroupAssoc.

PS: Votre DDL ressemble vraiment à un (M: N) relation entre MESSAGE et GROUP (ou je ne comprends pas la contrainte de PK de GROUP_ASSOC) mais vous ne montrait aucune contrainte FK sur GROUP_ID donc je suis pas sûr à 100%. Mais si c'est le cas, alors vous devriez utiliser un @ManyToMany au lieu de @OneToMany.

+0

Merci beaucoup pour votre aide. J'aurais dû mentionner que notre application doit afficher groupIds (dans l'interface utilisateur) et que cette liste de groupId est ce que nous devons finalement rechercher par message. Je pense que c'est une relation M: N car deux massages peuvent partager les mêmes groupIds. – Lightbeard

+0

Mon DDL est ma meilleure estimation quant à la façon de modéliser efficacement cette liste d'entiers afin qu'il puisse y avoir un problème avec cela (je suis un développeur d'interface utilisateur et non un DBA). Il semble fastidieux de créer un pojo 'GroupAssoc' séparé, en particulier si nous devons créer une troisième classe d'identité (puisqu'elle a une clé primaire composite) juste pour demander une liste de groupIds pour un message donné. – Lightbeard

+0

@Robert Vous n'auriez pas à créer une troisième entité, l'abstraction de JPA l'implémentation au niveau de la base de données. Donc, vous obtiendrez une liste de 'GroupAssoc' et itérez sur la liste pour obtenir chaque identifiant. –

Questions connexes