| Summary: | Conflict between @IdClass and indirection | ||||||
|---|---|---|---|---|---|---|---|
| Product: | z_Archived | Reporter: | Andrei Ilitchev <andrei.ilitchev> | ||||
| Component: | Eclipselink | Assignee: | Project Inbox <eclipselink.orm-inbox> | ||||
| Status: | CLOSED FIXED | QA Contact: | |||||
| Severity: | normal | ||||||
| Priority: | P3 | CC: | michael.f.obrien | ||||
| Version: | unspecified | ||||||
| Target Milestone: | --- | ||||||
| Hardware: | PC | ||||||
| OS: | Windows XP | ||||||
| Whiteboard: | |||||||
| Attachments: |
|
||||||
Created attachment 176575 [details]
Suggested patch
Eclipselink needs to access the attribute of IdClass corresponding to entity's id attribute: it's required that either attribute names or property names must be the same.
First Eclipselink tries to invoke "woman" field on PartnerLinkPK - that doesn't work in this case.
Next - in case of property access - it attempts to invoke "getWoman" property accessor on PartnerLinkPK. That should have worked, but LAZY fetch type was weaved into the entity and entity's accessor is no longer the original "getWoman" method, but the new Eclipselink-genarated "_persistence_getWoman_vh".
To fix the problem Eclipselink should keep somewhere the old method name and access here - so the patch adds this info to WeavedBasicIndirectionPolicy.
Changed the test class PartnerLink to use LAZY in both id attributes (to reproduce the problem), also altered getMsanId, getWomanId methods to be @Transient.
The patch checked into trunk and 2.1.1 Reviewed by Chris. >Note: the secondary NPE on missing _vh_ weaved functions is changed to a DescriptorException with suggestions in bug # 323403
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink |
Happens when field name(s) are different in Entity and its IdClass and id is arelation that weaved for indirection. To reproduce, in org.eclipse.persistence.testing.models.jpa.advanced.PartnerLink entity define both properties as lazy: @Entity @Table(name="MW") @IdClass(org.eclipse.persistence.testing.models.jpa.advanced.PartnerLinkPK.class) public class PartnerLink { private Man man; private Woman woman; public PartnerLink() {} @Id @OneToOne(cascade=PERSIST, fetch=LAZY) @JoinColumn(name="M") public Man getMan() { return man; } @Id @OneToOne(cascade=PERSIST, fetch=LAZY) @JoinColumn(name="W") public Woman getWoman() { return woman; } ... Note that in the IdClass uses differently named fields: public class PartnerLinkPK { private int manId; private Integer womanId; ... Result: the persistence unit fails to deploy: Errors: TEST SUITE NAME: org.eclipse.persistence.testing.tests.jpa.advanced.EntityManagerJUnitTestSuite TEST NAME: testSetup(org.eclipse.persistence.testing.tests.jpa.advanced.EntityManagerJUnitTestSuite) ##FAILURE## RESULT: FatalError (error) javax.persistence.PersistenceException: Exception [EclipseLink-0] (Eclipse Persistence Services - @VERSION@.@QUALIFIER@): org.eclipse.persistence.exceptions.IntegrityException Descriptor Exceptions: --------------------------------------------------------- Exception [EclipseLink-0] (Eclipse Persistence Services - @VERSION@.@QUALIFIER@): org.eclipse.persistence.exceptions.DescriptorException Exception Description: An internal error occurred accessing the primary key object [202]. Internal Exception: java.lang.NoSuchMethodException: org.eclipse.persistence.testing.models.jpa.advanced.PartnerLinkPK._persistence_get_woman_vh() Descriptor: RelationalDescriptor(org.eclipse.persistence.testing.models.jpa.advanced.PartnerLink --> [DatabaseTable(MW)]) Runtime Exceptions: --------------------------------------------------------- java.lang.NullPointerException at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:408) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:157) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:214) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:202) at org.eclipse.persistence.testing.framework.junit.JUnitTestCase.getServerSession(JUnitTestCase.java:373) at org.eclipse.persistence.testing.tests.jpa.advanced.EntityManagerJUnitTestSuite.testSetup(EntityManagerJUnitTestSuite.java:359) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at junit.framework.TestCase.runTest(TestCase.java:168) at junit.framework.TestCase.runBare(TestCase.java:134) at org.eclipse.persistence.testing.framework.junit.JUnitTestCase.runBare(JUnitTestCase.java:466) at junit.framework.TestResult$1.protect(TestResult.java:110) at junit.framework.TestResult.runProtected(TestResult.java:128) at junit.framework.TestResult.run(TestResult.java:113) at junit.framework.TestCase.run(TestCase.java:124) at org.eclipse.persistence.testing.framework.TestExecutor.execute(TestExecutor.java:248) at org.eclipse.persistence.testing.framework.TestExecutor.runTest(TestExecutor.java:671) at org.eclipse.persistence.testing.framework.ui.SynchronizedTestExecutor.run(SynchronizedTestExecutor.java:61) Caused by: Exception [EclipseLink-0] (Eclipse Persistence Services - @VERSION@.@QUALIFIER@): org.eclipse.persistence.exceptions.IntegrityException Descriptor Exceptions: --------------------------------------------------------- Exception [EclipseLink-0] (Eclipse Persistence Services - @VERSION@.@QUALIFIER@): org.eclipse.persistence.exceptions.DescriptorException Exception Description: An internal error occurred accessing the primary key object [202]. Internal Exception: java.lang.NoSuchMethodException: org.eclipse.persistence.testing.models.jpa.advanced.PartnerLinkPK._persistence_get_woman_vh() Descriptor: RelationalDescriptor(org.eclipse.persistence.testing.models.jpa.advanced.PartnerLink --> [DatabaseTable(MW)]) Runtime Exceptions: --------------------------------------------------------- java.lang.NullPointerException at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:471) at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:406) at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:666) at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.login(DatabaseSessionImpl.java:628) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:230) at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:380) ... 19 more