2009-06-04 11 views
10

J'essaie de mapper un objet @Embeddable dans une sous-classe dont la classe parent possède déjà un champ de ce type @Embeddable.Hibernate mappant un second champ @Embeddable dans une sous-classe

La mise en veille prolongée Embeddable Objects documentation revendications peuvent utiliser le @AttributeOverrides pour remplacer les noms de colonnes d'un objet @Embeddable:

par exemple

@Entity 
public class Person implements Serializable { 

    // Persistent component using defaults 
    Address homeAddress; 

    @Embedded 
    @AttributeOverrides({ 
      @AttributeOverride(name="iso2", column = @Column(name="bornIso2")), 
      @AttributeOverride(name="name", column = @Column(name="bornCountryName")) 
    }) 
    Country bornIn; 
    ... 
} 

est ici le cas je:

@Embeddable 
    public class ContentID implements Serializable { 
     @Column(name="contentID") 
     private String contentPath; 
    } 

    @MappedSuperclass 
    public abstract class BaseDomainObject implements Serializable { 

     @Embedded 
     private ContentID contentID; 
    } 

public class Achievement extends BaseDomainObject { 

    @Embedded 
    @AttributeOverrides({ 
     @AttributeOverride(name="contentID", column = @Column(name="awardedItem")), 
    }) 
    private ContentID awardedItem; 
} 

L'erreur que je reçois est:

org.hibernate.MappingException: colonne répétée en correspondance pour l'entité: colonne de réalisation: contentID (doit être mappé avec insert = "false" update = "false") à org.hibernate.mapping.PersistentC lass.checkColumnDuplication (PersistentClass.java:652) à org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication (PersistentClass.java:674) à org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication (PersistentClass.java:670) à org.hibernate.mapping.PersistentClass.checkColumnDuplication (PersistentClass.java:696) à org.hibernate.mapping.PersistentClass.validate (PersistentClass.java:450) à org.hibernate.mapping.SingleTableSubclass.validate (SingleTableSubclass .java: 43) at org.hibernate.cfg.Configuration.validate (Configuration.java:1108) at org.hibernate.cfg.Configuration.buildSessionFactory (Configuration.java:1293) à org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory (AnnotationConfiguration.java:867)

UPDATE:

J'ai regardé dans Hibernate les problèmes liés à cela et le projet GRAILS a affirmé avoir corrigé ce problème mais leur solution d'annotation ne semble pas être valide pour les annotations javax.persistence (c'est peut-être une nouvelle version).

JPA @Embeddable/@Embedded throws org.hibernate.MappingException: Repeated column in mapping for entity

+0

Par curiosité: Pourquoi intégrez-vous le pays au lieu d'utiliser une relation? –

Répondre

7

Le problème semble être ceci:

public class ContentID implements Serializable { 
    @Column(name="contentID") 
    private String contentPath; 
} 

Vous faites le nom de colonne contentPath être « contentId » et qui est avec l'annotation se heurtant de AttributeOverride plus tard.

Essayez ceci:

public class ContentID implements Serializable { 
    @Column(name="contentPath") 
    private String contentPath; 
} 

MISE À JOUR Je me demande aussi à ce sujet:

@Embedded 
@AttributeOverrides({ 
    @AttributeOverride(name="contentID", column = @Column(name="awardedItem")), 
}) 
private ContentID awardedItem; 

Vous semblez être changer le nom de la colonne contentId ici pour awardedItem. Est-ce vraiment nécessaire?

+0

Le problème n'est pas dû à @AttributeOverride dans Achievement, mais à cause du @Embedded ContentID qui se trouve dans la classe de base Achievement BaseDomainObject. Le problème réside dans les mappages d'hibernation. L'héritage fait que l'objet possède 2 objets ContentID incorporés en tant que colonne contentID, ce que je pensais qu'AtributeOverride s'en chargerait. Même si j'ai supprimé la @Column (name = "contentID"), je pense que le problème persisterait. – Dougnukem

1

J'utilise

@JoinColumn(insertable=false, updatable=false) 

comme solution de contournement.

2

Vincent a raison. Le champ attributeOverride Name fait référence à un nom de colonne lorsqu'il doit s'agir d'un attribut/propriété d'une classe.

@AttributeOverrides({ 
    @AttributeOverride(name="contentPath", column = @Column(name="awardedItem")), 
}) 

Notez que le nom est pour la propriété de classe et non la colonne de base de données.

Voir documentation