| Summary: | NPE when mapping chain of 2 multi-column relationships using JPA 2.0 and @EmbeddedId composite PK-FK | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| Product: | z_Archived | Reporter: | Karsten Wutzke <kwutzke> | ||||||
| Component: | Eclipselink | Assignee: | Guy Pelletier <guy.pelletier> | ||||||
| Status: | RESOLVED FIXED | QA Contact: | |||||||
| Severity: | critical | ||||||||
| Priority: | P2 | CC: | eclipselink.orm-inbox, gordon.yorke, guy.pelletier, kwutzke, michael.f.obrien, tom.ware | ||||||
| Version: | unspecified | ||||||||
| Target Milestone: | --- | ||||||||
| Hardware: | PC | ||||||||
| OS: | Windows 7 | ||||||||
| URL: | http://stackoverflow.com/questions/4288531/jpa-hibernate-eclipselink-mapping-why-doesnt-this-code-work-chain-of-2-rela | ||||||||
| Whiteboard: | |||||||||
| Attachments: |
|
||||||||
I'd really like to know what the JPA defined in that situation... Created attachment 184168 [details]
SSCCE: non-working example using transitive, nested composite primary key classes
If you haven't done so, it is likely a good idea to go through the mailing lists or forums prior to posting these kinds of bugs. The reason: There is a good chance someone will be able to provide you with a reasonable workaround. >Verify not related to or since Jan 2010 changes in bug# 300051
- this change only moved up the validation check on multiple embeddedId's
At the very least this null pointer exception is a bug. Created attachment 185775 [details]
Proposed changes
Patch corrects the NPE.
Changes have been submitted. Reviewed by: Tom Ware Tests: No, metadata processing exception. With this change, that exception goes away and all tests (FullRegressionTestSuite and extended JPA) pass successfully. The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink |
I have three tables: 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) ); Simple logic: Bars -> Foos -> PostAddresses all by (contact_id, ordinal_nbr), whatever it means. Here the six entity and respective composite key classes. @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; ... } It's really nothing special, Bar references Foo, Foo references PostAddress, all via composite key class. Since the foreign keys are composite and part of the PK, I must nest the ID classes into the ID classes. I thought this is correct. However, I get the following stack trace with EclipseLink 2.2.0: 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: sun.misc.Launcher$AppClassLoader@1f7182c1 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 gives me absolutely no hint as to which class is the offending one. I found out using Hibernate telling me about a problem with the @MapsId annotation and the Foo class: org.hibernate.AssertionFailure: Unexpected nested component on the referenced entity when mapping a @MapsId: tld.transmuc.model.Foo It appears to be an EclipseLink bug. Even if I omit the @Embedded annotation from the ID classes, the exception is still there.