Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 331480

Summary: [Validation] Need validation for embeddable id class
Product: [WebTools] Dali JPA Tools Reporter: Nan Li <nan.n.li>
Component: JPAAssignee: Leslie Davis <les.davis>
Status: RESOLVED FIXED QA Contact:
Severity: enhancement    
Priority: P3 CC: karenfbutzke, les.davis, neil.hauge
Version: unspecifiedKeywords: plan
Target Milestone: 3.2 M6Flags: karenfbutzke: review+
Hardware: PC   
OS: Windows 7   
Whiteboard:
Attachments:
Description Flags
proposed bug fix patch
none
patch with additional recommended changes
none
proposed patch neil.hauge: iplog+

Description Nan Li CLA 2010-11-30 17:05:14 EST
Build Identifier: 20100917-0705

1. Embedded id class must include method definitions for equals() and
hashcode()
2. The fields or properties of the embedded id class must be in the set of
valid identifier types (Pro EJB 3 book P83) (too ambiguous to validate? too restrictive?)
3. Embedded id class must be public, implement Serializable, and have a
no-arg constructor
4. No @Id nor @IdClass is used in the entity that uses the embedded id class (validation for @IdClass exists)
5. Embedded id class must be annotated with @Embeddable (validation exists)
6. The access type of the embedded id class must match the access type of the
entity that uses it

Corresponding validation message(s) should be given when any of the rules
above is violated. 

Reproducible: Always

Steps to Reproduce:
1. Create an id class
2. Create a java entity making the type of its primary key attribute as the id class and annotating its primary key attribute with @EmbeddedId
Comment 1 Leslie Davis CLA 2011-03-08 16:45:41 EST
For item 1:  

This will be a warning as they are not explicitly mentioned in the spec and EclipseLink does not validate on this.  The warning message should read "Embedded id class should include method definitions for equals(Object) and hashcode()"

I will add methods to JDTTools for determining if the given type name define particular method signatures and create validation methods on GenericJavaEmbeddedIdMapping and GenericOrmEmbeddedIdMapping which use the JDTTools methods to determine whether the target embeddable type defines these methods and add the warning message if not.
Comment 2 Leslie Davis CLA 2011-03-09 14:43:48 EST
For item 2:

I feel this is may be too restrictive as mentioned, might be a "nice to have" warning however?

For item 3:

This, like item 1, is more a general rule for primary key classes and would be a warning as well.  The warning message should read "Embedded id class should be public, implement Serializable, and include a zero argument constructor" 

JDTTools already contains a method to determine if the class implements Serializable typeNamedImplementsInterfaceNamed(), and will contain classHasPublicZeroArgConstructor when a previous patch from Nan is checked in.  Validation methods on GenericJavaEmbeddedIdMapping and GenericOrmEmbeddedIdMapping  will uses these methods to determine whether the target embeddable type meets these requirements and add the warning message if not.
Comment 3 Leslie Davis CLA 2011-03-09 15:01:39 EST
For item 4:

This is specified in the spec and would be an error.  The error message should read "Id or id class is defined on another attribute/property on the parent entity, only one or the other may be defined on an entity"

Validation methods added to GenericOrmEmbeddedIdMapping and GenericOrmEmbeddedIdMapping would be added to look at all other persistent attributes and properties on the entity for id or id class definitions.
Comment 4 Leslie Davis CLA 2011-03-09 17:58:45 EST
For Item 5:

Validation already exists

For Item 6:

Page 280 of Pro JPA 2 the second paragraph under the heading "Embedded Id Class" appears to state the opposite, "Like other embedded objects, the embedded id class must be annotated with @Embeddable, but the
access type might differ from that of the entity that uses it."
Comment 5 Leslie Davis CLA 2011-03-09 18:00:01 EST
I would also suggest adding validation for this from the spec:

"Relationship mappings defined within an embedded id class are not
supported."
Comment 6 Neil Hauge CLA 2011-03-11 17:25:40 EST
(In reply to comment #1)
> For item 1:  
> 
> This will be a warning as they are not explicitly mentioned in the spec and
> EclipseLink does not validate on this.  The warning message should read
> "Embedded id class should include method definitions for equals(Object) and
> hashcode()"
> 
> I will add methods to JDTTools for determining if the given type name define
> particular method signatures and create validation methods on
> GenericJavaEmbeddedIdMapping and GenericOrmEmbeddedIdMapping which use the
> JDTTools methods to determine whether the target embeddable type defines these
> methods and add the warning message if not.

I think this can be an error message based on JPA 2.0 spec section 2.4.  For the error message, use "... equals() and hashcode()".  

(In reply to comment #2)
> For item 2:
> 
> I feel this is may be too restrictive as mentioned, might be a "nice to have"
> warning however?

We don't yet do this validation for basic id's yet, so this can wait for now.


> For item 3:
> 
> This, like item 1, is more a general rule for primary key classes and would be
> a warning as well.  The warning message should read "Embedded id class should
> be public, implement Serializable, and include a zero argument constructor" 
> 

This needs to be split up a bit.  Public and zero argument constructor validation can be combined in one message.  This should be an error based on section 2.4 of the spec.

Implements Serializable should also be an error based on section 2.4 of the spec.

> JDTTools already contains a method to determine if the class implements
> Serializable typeNamedImplementsInterfaceNamed(), and will contain
> classHasPublicZeroArgConstructor when a previous patch from Nan is checked in. 
> Validation methods on GenericJavaEmbeddedIdMapping and
> GenericOrmEmbeddedIdMapping  will uses these methods to determine whether the
> target embeddable type meets these requirements and add the warning message if
> not.


(In reply to comment #3)
> For item 4:
> 
> This is specified in the spec and would be an error.  The error message should
> read "Id or id class is defined on another attribute/property on the parent
> entity, only one or the other may be defined on an entity"
> 
> Validation methods added to GenericOrmEmbeddedIdMapping and
> GenericOrmEmbeddedIdMapping would be added to look at all other persistent
> attributes and properties on the entity for id or id class definitions.

This probably needs to be type level validation that results in an error when it's collection of mappings contain a simple Id and an Embedded Id.  You will need to look at what AbstractPrimaryKeyValidator is doing (and its subclasses) to get an idea of what is taking place related to Id validation.  Much care is needed when adding validation in this area and differences between Generic and EclipseLink are important, as EclipseLink is less restrictive in many cases.  As for this particular error, I don't think EclipseLink is less restrictive.  


(In reply to comment #4)
> For Item 5:
> 
> Validation already exists
> 
> For Item 6:
> 
> Page 280 of Pro JPA 2 the second paragraph under the heading "Embedded Id
> Class" appears to state the opposite, "Like other embedded objects, the
> embedded id class must be annotated with @Embeddable, but the
> access type might differ from that of the entity that uses it."

This is also backed up by the spec, section 2.4.

(In reply to comment #5)
> I would also suggest adding validation for this from the spec:
> 
> "Relationship mappings defined within an embedded id class are not
> supported."

Yes, please add this to the Embedded Id validation.
Comment 7 Leslie Davis CLA 2011-03-31 14:54:41 EDT
Created attachment 192311 [details]
proposed bug fix patch
Comment 8 Neil Hauge CLA 2011-04-04 12:07:14 EDT
Deferring this to 3.1.  Slightly too much risk to add this validation to the 3.0 release at this point.
Comment 9 Nan Li CLA 2011-04-04 13:36:16 EDT
*** Bug 341821 has been marked as a duplicate of this bug. ***
Comment 10 Neil Hauge CLA 2011-07-01 16:24:19 EDT
Moving JPA specific bugs to new JPA component in bugzilla.
Comment 11 Karen Butzke CLA 2011-08-16 12:33:44 EDT
validation preferences are needed for these new messages (see JpaProblemSeveritiesPage)

For Item 3:
the zero arg constructor validation was added with bug 132216, so now that message can just be for making sure the class is public. Currently we end up with 2 validation messages about needing a zero-arg constructor

minor, but this is misspelled - EMBEDDED_ID_CLASS_SHOULD_IMPLMENT_EQUALS_HASHCODE

In JDTTools.typeImplementsMethod(IJavaProject, IType, String, String[]) no need to pass in the IJavaProject, it is not used.

In GenericJavaEmbeddedIdMapping - validateTargeEmbeddableImplementsEqualsAndHashcode - typo - missing the t on the end of Target
Comment 12 Karen Butzke CLA 2011-08-16 12:46:32 EDT
The method JDTTools.classIsPublic(IJavaProject, String) is unnecessary. I just added API TypeMapping.getJavaResourceType() and JavaResourceType already has the API isPublic(), so that can be used instead of this new method in JDTTools.

I am going to look at removing JDTTools.classHasPublicZeroArgConstructor() as well, since that is somewhat redundant with API on JavaResourceType, just need to figure out which one is more correct.
Comment 13 Leslie Davis CLA 2011-09-14 18:18:26 EDT
Created attachment 203372 [details]
patch with additional recommended changes

Fixed compilation problems and implemented suggested changes.
Comment 14 Karen Butzke CLA 2011-09-20 10:48:41 EDT
Les, I have to send this back at you again because it doesn't take into account virtual attributes in an orm.xml file. The validation messages do not have enough information to understand the context if an entity is added to the orm.xml file that contains a virtual embeddedId with any of these validation errors.
Comment 15 Karen Butzke CLA 2011-09-20 11:18:13 EDT
And a couple minor things I was changing in the patch, so I don't forget with the next patch: 


TYPE_MAPPING_ID_AND_EMBEDDED_ID_BOTH_USED=This class must use either an ID or **and** embedded ID to specify its primary key, not both

**and** should be *an*

Also remove the '.' from the end of all the validation messages. That will match our other validation messages and the JDT messages.
Comment 16 Leslie Davis CLA 2012-02-14 15:02:39 EST
Created attachment 211005 [details]
proposed patch

Added validation for virtual attributes.
Comment 17 Karen Butzke CLA 2012-02-29 10:23:51 EST
checked patch in for M6