This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
Bug 288972 - JPA2: New MappedSuperclass metadata preprocessing for metamodel raises ValidationException for composite PK on MappedSuperclass chain
Summary: JPA2: New MappedSuperclass metadata preprocessing for metamodel raises Valida...
Status: RESOLVED FIXED
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows Vista
: P2 normal (vote)
Target Milestone: ---   Edit
Assignee: Nobody - feel free to take it CLA
QA Contact:
URL: http://wiki.eclipse.org/EclipseLink/D...
Whiteboard:
Keywords:
Depends on:
Blocks: 266912
  Show dependency tree
 
Reported: 2009-09-09 14:37 EDT by Michael OBrien CLA
Modified: 2022-06-09 10:25 EDT (History)
1 user (show)

See Also:


Attachments
DI 78: This patch is for community reference and discussion only - a final revised patch will be submitted for review before checkin (12.13 KB, patch)
2009-11-18 09:57 EST, Michael OBrien CLA
no flags Details | Diff
DI 78: This patch is for community reference and discussion only - a final revised patch will be submitted for review before checkin (23.53 KB, patch)
2009-11-18 21:28 EST, Michael OBrien CLA
no flags Details | Diff
DI 78: skip initialization of @Id mappings declared above on MappedSuperclass chains during Entity deploy() processing in ClassDescriptor and ObjectBuilder : pre-code review (21.50 KB, patch)
2009-11-19 09:31 EST, Michael OBrien CLA
no flags Details | Diff
DI 78: Code review 1 (47.05 KB, patch)
2009-11-20 00:45 EST, Michael OBrien CLA
no flags Details | Diff
original model invalid - adjusted test model has no issues (22.03 KB, patch)
2009-11-22 23:47 EST, Michael OBrien CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Michael OBrien CLA 2009-09-09 14:37:26 EDT
> An Entity --> MappedSuperclass(ID1) --> MappedSuperclass(ID2) causes a new ValidationException for a composite PK spread across an inherited MappedSuperclass chain.  Why? because we are processing MappedSuperclass descriptors as of rev# 4587

>see
http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_78:_20090909:_Composite_.40IdClass_on_inherited_MappedSuperclass_chain_causes_new_ValidationException

>reproduction and stacktrace are pending and will be on the wiki
Comment 1 Michael OBrien CLA 2009-09-16 15:34:06 EDT
>commit to fix this behavior change by 2.0
>Work on this bug should start around 25 Sept 2009
Comment 2 Michael OBrien CLA 2009-10-14 09:49:05 EDT
>starting investigation now
Comment 3 Michael OBrien CLA 2009-11-11 16:15:35 EST
>Starting reproduction 20091111
We are now throwing a validation exception after the metadata changes to preprocess the metamodel descriptors for MappedSuperclasses in the case where there is an @IdClass in a MappedSuperclass above an @Id - this is invalid and used to be ignored.
>Note: This occurs only for Id fields - if you remove the single @Id on the center MappedSuperclass - this validation exception does not occur.

>Model
-------------------------
@MappedSuperclass
@IdClass(org.eclipse.persistence.testing.models.jpa.metamodel.MSIdClassPK.class)
public abstract class MS_MS_Entity_Root implements java.io.Serializable {
    @Id
    @Column(name="TYPE")
    public String type;
    @Id
    @Column(name="LENGTH")
    protected String length;
    @Id
    @Column(name="WIDTH")
    private String width;
}

@MappedSuperclass
public abstract class MS_MS_Entity_Center extends MS_MS_Entity_Root {
>   @Id
    @Column(name="MSMSENTITY_ID")    
    private Integer ident;
}

@Entity(name="MS_MS_EntityLeafMetamodel")
@Table(name="CMP3_MM_MSMSENTITY_LEAF")
public class MS_MS_Entity_Leaf extends MS_MS_Entity_Center {}


>Table generation
------------------------
// commented code aligns with commented @Id to remove the exception
    public static TableDefinition buildMS_MS_Entity_Leaf_Table() {
        TableDefinition table = new TableDefinition();
        table.setName("CMP3_MM_MSMSENTITY_LEAF");

        // From (MS)-MS-Entity root
        FieldDefinition field13 = new FieldDefinition();
        field13.setName("TYPE");
        field13.setTypeName("VARCHAR");
        field13.setSize(80);
        field13.setShouldAllowNull(false);
        field13.setIsPrimaryKey(true);
        field13.setUnique(false);
        field13.setIsIdentity(true);
        table.addField(field13);

        FieldDefinition field14 = new FieldDefinition();
        field14.setName("LENGTH");
        field14.setTypeName("VARCHAR");
        field14.setSize(80);
        field14.setShouldAllowNull(false);
        field14.setIsPrimaryKey(true);
        field14.setUnique(false);
        field14.setIsIdentity(true);
        table.addField(field14);

        FieldDefinition field15 = new FieldDefinition();
        field15.setName("WIDTH");
        field15.setTypeName("VARCHAR");
        field15.setSize(80);
        field15.setShouldAllowNull(false);
        field15.setIsPrimaryKey(true);
        field15.setUnique(false);
        field15.setIsIdentity(true);
        table.addField(field15);

        // From MS-(MS)-Entity center
        FieldDefinition field = new FieldDefinition();
        field.setName("MSMSENTITY_ID");
        field.setTypeName("NUMERIC");
        field.setSize(15);
        field.setShouldAllowNull(false);
        //field.setIsPrimaryKey(false);//true);
        field.setIsPrimaryKey(true);
        field.setUnique(false);
        //field.setIsIdentity(false);//true);
        field.setIsIdentity(true);
        table.addField(field);
        
        FieldDefinition field4 = new FieldDefinition();
        field4.setName("MSMSENTITY_VERSION");
        field4.setTypeName("NUMERIC");
        field4.setSize(15);
        field4.setShouldAllowNull(true);
        field4.setIsPrimaryKey(false);
        field4.setUnique(false);
        field4.setIsIdentity(false);
        table.addField(field4);        
        return table;
    }



>Trace
------------------------

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.NoSuchFieldException: ident
Descriptor: RelationalDescriptor(org.eclipse.persistence.testing.models.jpa.metamodel.MS_MS_Entity_Leaf --> [DatabaseTable(CMP3_MM_MSMSENTITY_LEAF)])
Runtime Exceptions: 
---------------------------------------------------------
	at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:390)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:151)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:207)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:195)
	at org.eclipse.persistence.testing.framework.junit.JUnitTestCase.getServerSession(JUnitTestCase.java:340)
	at org.eclipse.persistence.testing.framework.junit.JUnitTestCase.getEntityManagerFactory(JUnitTestCase.java:365)
	at org.eclipse.persistence.testing.framework.junit.JUnitTestCase.getEntityManagerFactory(JUnitTestCase.java:344)
	at org.eclipse.persistence.testing.tests.jpa.metamodel.MetamodelTest.initialize(MetamodelTest.java:84)
	at org.eclipse.persistence.testing.tests.jpa.metamodel.MetamodelTest.initialize(MetamodelTest.java:65)
	at org.eclipse.persistence.testing.tests.jpa.metamodel.MetamodelTest.setUp(MetamodelTest.java:54)
	at org.eclipse.persistence.testing.tests.jpa.metamodel.MetamodelTest.setUp(MetamodelTest.java:49)
	at org.eclipse.persistence.testing.tests.jpa.metamodel.EntityManagerFactoryImplTest.setUp(EntityManagerFactoryImplTest.java:46)

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.NoSuchFieldException: ident
Descriptor: RelationalDescriptor(org.eclipse.persistence.testing.models.jpa.metamodel.MS_MS_Entity_Leaf --> [DatabaseTable(CMP3_MM_MSMSENTITY_LEAF)])

Runtime Exceptions: 
---------------------------------------------------------

	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:478)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:406)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:671)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.login(DatabaseSessionImpl.java:633)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:230)
	at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:366)

>This is an invalid configuration - I recommend we let this warning occur in our new MappedSuperclass descriptor validation - and not suppress it.
Comment 4 Michael OBrien CLA 2009-11-12 07:40:51 EST
>However, we should temporarily suspend validation for pseudo MappedSuperclass Descriptor partial processing (no initialization - is why we do not find the field yet) - during stage 2 in
    MetadataProject.processStage2() for m_metamodelMappedSuperclasses
Comment 5 Michael OBrien CLA 2009-11-18 09:57:19 EST
Created attachment 152478 [details]
DI 78: This patch is for community reference and discussion only - a final revised patch will be submitted for review before checkin
Comment 6 Michael OBrien CLA 2009-11-18 21:28:01 EST
Created attachment 152547 [details]
DI 78: This patch is for community reference and discussion only - a final revised patch will be submitted for review before checkin

>Added more granular truncation of initialization in ObjectBuilder for MappedSuperclass defined id mappings
Comment 7 Michael OBrien CLA 2009-11-19 09:31:39 EST
Created attachment 152584 [details]
DI 78: skip initialization of @Id mappings declared above on MappedSuperclass chains during Entity deploy() processing in ClassDescriptor and ObjectBuilder : pre-code review
Comment 8 Michael OBrien CLA 2009-11-20 00:45:44 EST
Created attachment 152673 [details]
DI 78: Code review 1

Problem summary:
------------------
When we have a composite PK IdClass defined where the id mappings are spread across 2 or more MappedSuperclasses in an inheritance tree, we are unable to initialize the id mappings on the center mappedSuperclass because the other inherited id mappings are only copied to the first Entity leaf in the chain (and skip the middle mappedSuperclass).
We will
- add isJPAIdClass field to DatabaseMapping - so we don't have to search the IdClassMap on the core project
- add isMappedSuperclassMapping to store the accessor type on the DatabaseMapping
- only skip Id initialization if all the id's are not defined on the current MappedSuperclass


TEST MODEL NAME: (JUnit test): Metamodel
Errors: (failures): 0
Fatal Errors: (errors): 0
Passed: 124
Total Tests: 124

TEST MODEL NAME: (JUnit test): Criteria
Errors: (failures): 0
Fatal Errors: (errors): 0
Passed: 134
Total Tests: 134
Comment 9 Michael OBrien CLA 2009-11-22 23:47:05 EST
Created attachment 152821 [details]
original model invalid - adjusted test model has no issues

>20091122 the model is wrong.
We must ensure that we have access to the IdClass attribute where we define @IdClass.
In the case of the model above - the 4th @Id on the middle subclass mappedSuperclass is not accessible from the top root.

>Model
-------------------------
@MappedSuperclass
@IdClass(org.eclipse.persistence.testing.models.jpa.metamodel.MSIdClassPK.class) // invalid - should be one level down
public abstract class MS_MS_Entity_Root implements java.io.Serializable {
    @Id    protected String type;
    @Id    protected String length;
    @Id    protected String width;
}

@MappedSuperclass
public abstract class MS_MS_Entity_Center extends MS_MS_Entity_Root {
>   @Id    protected Integer ident;
}

@Entity(name="MS_MS_EntityLeafMetamodel")
public class MS_MS_Entity_Leaf extends MS_MS_Entity_Center {}

>should be 
>Model
-------------------------
@MappedSuperclass
public abstract class MS_MS_Entity_Root implements java.io.Serializable {
    @Id    protected String type;
    @Id    protected String length;
    @Id    protected String width;
}

@MappedSuperclass
@IdClass(org.eclipse.persistence.testing.models.jpa.metamodel.MSIdClassPK.class) // or defined on the entity
public abstract class MS_MS_Entity_Center extends MS_MS_Entity_Root {
>   @Id    protected Integer ident;
}

@Entity(name="MS_MS_EntityLeafMetamodel")
public class MS_MS_Entity_Leaf extends MS_MS_Entity_Center {}
Comment 10 Michael OBrien CLA 2009-11-23 00:30:30 EST
>Invalid model - bug closed and test model fixed.
It turns out that the reproduction model for an IdClass distributed among multiple MappedSuperclasses was incorrect.  There were two issues: 1) the IdClass itself only defined 3 or the 4 Id attributes and 2) the @IdClass annotation should have been either 1 or 2 levels down on the center MappedSuperclass or the leaf Entity.
The result of this was I was trying to suppress a valid integrity warning on the missing id that was not visible from the top root MappedSuperclass.  After discussing this with 4 senior members of my JPA team I see that the integrity of the IdClass drives the placement of the @IdClass annotation.
 
http://fisheye2.atlassian.com/changelog/eclipselink/?cs=5849
Comment 11 Eclipse Webmaster CLA 2022-06-09 10:25:08 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink