2010-11-26 18 views
5

私は3つのテーブルを持っています:JPA(Hibernate、EclipseLink)マッピング:JPA 2.0、@EmbeddedId複合PK-FKを使用して2つの関係の連鎖ができないのはなぜですか?

CREATE TABLE PostAddresses 
(
    contact_id INTEGER NOT NULL, 
    ordinal_nbr SMALLINT NOT NULL, 
    PRIMARY KEY (contact_id, ordinal_nbr) 
); 

CREATE TABLE Foos 
(
    contact_id INTEGER NOT NULL, 
    ordinal_nbr SMALLINT NOT NULL, 
    PRIMARY KEY (contact_id, ordinal_nbr), 
    FOREIGN KEY (contact_id, ordinal_nbr) REFERENCES PostAddresses (contact_id, ordinal_nbr) 
); 

CREATE TABLE Bars 
(
    contact_id INTEGER NOT NULL, 
    ordinal_nbr SMALLINT NOT NULL, 
    numba INTEGER NOT NULL, 
    PRIMARY KEY (contact_id, ordinal_nbr, numba), 
    FOREIGN KEY (contact_id, ordinal_nbr) REFERENCES Foos (contact_id, ordinal_nbr) 
); 

単純なロジック:Bars - > Foos - > PostAddresses by(contact_id、ordinal_nbr)

6つのエンティティとそれぞれの複合キークラス。

@Entity 
@Table(name = "PostAddresses") 
public class PostAddress implements Serializable 
{ 
    @EmbeddedId 
    private PostAddressId embeddedId; 

    ... 
} 

@Embeddable 
public class PostAddressId implements Serializable 
{ 
    @Column(name = "contact_id") 
    private Integer contactId; 

    @Column(name = "ordinal_nbr") 
    private Integer ordinalNbr = 1; 

    ... 
} 

@Entity 
@Table(name = "Foos") 
public class Foo implements Serializable 
{ 
    @EmbeddedId 
    private FooId embeddedId; 

    @MapsId(value = "postAddressId") 
    @OneToOne 
    @JoinColumns(value = {@JoinColumn(name = "contact_id", referencedColumnName = "contact_id"), @JoinColumn(name = "ordinal_nbr", referencedColumnName = "ordinal_nbr")}) 
    private PostAddress postAddress = null; 

    ... 
} 

@Embeddable 
public class FooId implements Serializable 
{ 
    @Embedded 
    private PostAddressId postAddressId; //just one field! 

    ... 
} 

@Entity 
@Table(name = "Bars") 
public class Bar implements Serializable 
{ 
    @EmbeddedId 
    private BarId embeddedId; 

    ... 
} 

@Embeddable 
public class BarId implements Serializable 
{ 
    @Embedded 
    private FooId fooId; 

    @Column(name = "numba") 
    private Integer numba; 

    ... 
} 

BarはFooを参照し、FooはPostAddressを参照します。これらはすべて複合キークラスを介して参照されます。外部キーはコンポジットでPKの一部なので、IDクラスをIDクラスにネストする必要があります。私はこれが正しいと思った。ただし、Hibernate 3.6とEclipseLink 2.2.0

Hibernateで次のスタックトレースを取得します。Hibernate:

org.hibernate.AssertionFailure: Unexpected nested component on the referenced entity when mapping a @MapsId: tld.transmuc.model.Foo 
    at org.hibernate.cfg.CopyIdentifierComponentSecondPass.doSecondPass(CopyIdentifierComponentSecondPass.java:101) 
    at org.hibernate.cfg.Configuration.processSecondPassesOfType(Configuration.java:1424) 
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1388) 
    at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1345) 
    at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1477) 
    at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:193) 
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1096) 
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:278) 
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:362) 
    at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:56) 
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48) 
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32) 
    at tld.transmuc.Main.main(Main.java:27) 
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: transmuc] Unable to configure EntityManagerFactory 
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:374) 
    at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:56) 
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48) 
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32) 
    at tld.transmuc.Main.main(Main.java:27) 
Caused by: org.hibernate.AssertionFailure: Unexpected nested component on the referenced entity when mapping a @MapsId: tld.transmuc.model.Foo 
    at org.hibernate.cfg.CopyIdentifierComponentSecondPass.doSecondPass(CopyIdentifierComponentSecondPass.java:101) 
    at org.hibernate.cfg.Configuration.processSecondPassesOfType(Configuration.java:1424) 
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1388) 
    at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1345) 
    at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1477) 
    at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:193) 
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1096) 
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:278) 
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:362) 
    ... 4 more 

EclipseLink:

Exception in thread "main" Local Exception Stack: 
Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.2.0.v20101118-r8514): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException 
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: [email protected] 
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.2.0.v20101118-r8514): org.eclipse.persistence.exceptions.EntityManagerSetupException 
Exception Description: Predeployment of PersistenceUnit [transmuc] failed. 
Internal Exception: java.lang.NullPointerException 
    at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:126) 
    at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:136) 
    at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:65) 
    at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source) 
    at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source) 
    at tld.transmuc.Main.main(Main.java:27) 
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.2.0.v20101118-r8514): org.eclipse.persistence.exceptions.EntityManagerSetupException 
Exception Description: Predeployment of PersistenceUnit [transmuc] failed. 
Internal Exception: java.lang.NullPointerException 
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1021) 
    at org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.callPredeploy(JPAInitializer.java:95) 
    at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:127) 
    ... 4 more 
Caused by: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.2.0.v20101118-r8514): org.eclipse.persistence.exceptions.EntityManagerSetupException 
Exception Description: Predeployment of PersistenceUnit [transmuc] failed. 
Internal Exception: java.lang.NullPointerException 
    at org.eclipse.persistence.exceptions.EntityManagerSetupException.predeployFailed(EntityManagerSetupException.java:210) 
    ... 7 more 
Caused by: java.lang.NullPointerException 
    at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.EmbeddedIdAccessor.process(EmbeddedIdAccessor.java:189) 
    at org.eclipse.persistence.internal.jpa.metadata.MetadataDescriptor.processMappingAccessors(MetadataDescriptor.java:1417) 
    at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor.processMappingAccessors(ClassAccessor.java:1405) 
    at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.processMappingAccessors(EntityAccessor.java:1061) 
    at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.process(EntityAccessor.java:601) 
    at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processStage2(MetadataProject.java:1464) 
    at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.processORMMetadata(MetadataProcessor.java:483) 
    at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processORMetadata(PersistenceUnitProcessor.java:453) 
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:975) 
    ... 6 more 

EclipseLinkでは、不快なもの。少なくともHibernateは@MapsIdアノテーションとFooクラスの問題について教えています:

org.hibernate.AssertionFailure: Unexpected nested component on the referenced entity when mapping a @MapsId: tld.transmuc.model.Foo 

何が間違っていますか?

PS:SSCCEをまとめることができます。必要があるかどうかを尋ねるだけです(JavaSE、HSQLDB、Ant、Hibernate 3.6)。

答えて

2

はあなたの問題を解決することがあります。:

 
    @Embeddable 
    public class FooId implements Serializable 
    { 
     // no annotation. 
     private PostAddressId postAddressId; //just one field! 

     ... 
    } 

    ... 
     @MapsId(value = "postAddressId") 
     @OneToOne 
     @JoinColumns(value = {@JoinColumn(name = "contact_id", referencedColumnName = "contact_id"), @JoinColumn(name = "ordinal_nbr", referencedColumnName = "ordinal_nbr")}) 
     private PostAddress postAddress = null; 

(EDIT):もう一つの問題は、FooIdの使用です。このクラスは使用しないでください。 Foo EnitityのIDクラスはPostAddressIdで、OneToOneの "postAddress"は単に@Idとマークされ、@MapsIdはマークされません。同様に、BarIdはEmbeddedを定義するべきではありませんが、PostAddressIdを直接参照する必要があります。 PostAddressを参照するバーマッピングではMapsIdを使用する必要があります。

恐ろしい例外については、EclipseLinkにバグを報告してください。@Embeddedを削除しても、他のアップデートが問題を解決しない場合は、EclipseLinkのバグを報告してください。

+0

投稿する前にこれを試してみましたが、もう一度試しましたが、@Embeddedの有無に関係なく動作しません。私は今バグを報告します。 – Kawu

+2

バグ報告を追加していただきありがとうございます。EclipseLinkのバグは、https://bugs.eclipse.org/bugs/show_bug.cgi?id=331386 – Kawu

+0

にあります。それは私の日を救った。私はまだEclipseLink 2.2.xを使用していますが、Eclipse 2.3.xを使用するようにpomを変更するだけで、このNPEの問題が修正されました。 – lsiu

関連する問題