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

Bug 306777

Summary: [JPA 2.0] Incorrect validation/defaults when maps-id is used on a relationship
Product: [WebTools] Dali JPA Tools Reporter: Paul Fullbright <paul.fullbright>
Component: GeneralAssignee: Paul Fullbright <paul.fullbright>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P2 CC: karenfbutzke, neil.hauge
Version: 2.3Flags: neil.hauge: pmc_approved? (david_williams)
neil.hauge: pmc_approved? (raghunathan.srinivasan)
neil.hauge: pmc_approved? (naci.dai)
neil.hauge: pmc_approved? (deboer)
neil.hauge: pmc_approved+
neil.hauge: pmc_approved? (kaloyan)
neil.hauge: review+
Target Milestone: 2.3 M7   
Hardware: PC   
OS: Windows Vista   
Whiteboard: PMC_approved
Bug Depends on:    
Bug Blocks: 294266, 294271    
Attachments:
Description Flags
proposed patch none

Description Paul Fullbright CLA 2010-03-22 18:32:08 EDT
There are several areas where validation and defaults are not calculated correctly when a relationship uses the maps id setting.

I: Id mapping that is mapped by a relationship (bug 294271) 

@Entity
public class Person {
    @Id
    String ssn;
}

@Entity
public class MedicalHistory {
    @Id
    String id; // overriding not allowed

    // default join column name ("patient_ssn") is overridden
    @MapsId("id")
    @JoinColumn(name="FK")
    @OneToOne
    Person patient;
}

In this case, the ssn attribute on Person should not have a default column, and it should also not validate its column.  In fact, there should be a validation error if the column *is* specified.


II: Embedded id mapping that is mapped by a relationship

@Embeddable
public class PersonId
{
	String firstName;
	
	String lastName;
}

@Entity(name = "Person_6")
public class Person {
	@EmbeddedId
	PersonId id;
}

@Entity(name = "MedicalHistory_6b")
public class MedicalHistory {
	@EmbeddedId
	PersonId id;
	
	@OneToOne
	@MapsId
	@JoinColumns({
		@JoinColumn(name="FK1", referencedColumnName="FIRSTNAME"),
		@JoinColumn(name="FK2", referencedColumnName="LASTNAME")})
	Person patient;
}

In this case, the id attribute on MedicalHistory should not have any implied attribute overrides (usually all attributes on PersonId would be implied, with appropriate default column and table name).  Any attribute overrides specified on the id attribute should in fact be invalidated.


III: Attribute override that is mapped by a relationship (bug 294266)

There are two ways to illustrate this.

IIIa.  Attribute override on an embedded id mapping

public class EmployeeId {
	String firstName;
	
	String lastName;
}

@Entity(name = "Employee_2")
@IdClass(EmployeeId.class)
public class Employee {
	@Id
	String firstName;
	
	@Id
	String lastName;
}

@Embeddable
public class DependentId {
	String name;
	
	EmployeeId empPk;
}

@Entity(name = "Dependent_2b")
public class Dependent {
	@EmbeddedId
	DependentId id;
	
	@ManyToOne
	@MapsId("empPk")
	@JoinColumns({
		@JoinColumn(name="FK1", referencedColumnName="FIRSTNAME"),
		@JoinColumn(name="FK2", referencedColumnName="LASTNAME")})
	Employee emp;
}

In this case, the attribute overrides "empPk.firstName" and "empPk.lastName" should not be defaulted in for the embedded id "id".  These attribute overrides already have columns associated via the subattribute "empPk" being mapped by the relationship.

IIIb. Attribute overrides on an entity

@MappedSuperclass
public abstract class Person {
	@Id
	int ssn;
}

@Entity
@Table(name = "Employee_7b")
public class Employee
	extends Person {
	
}

@Entity
@Table(name = "Dependent_7b")
public class Dependent extends Person {
	@ManyToOne
	@MapsId("ssn")
	protected Employee emp;
}

In this case, the attribute override "ssn" should not be defaulted in for the entity "Dependent".  This attribute override already has a column associated via the "ssn" attribute being mapped by the relationship.

In addition, for the above two cases, if attribute overrides have been specified, there should be a validation error.
Comment 1 Paul Fullbright CLA 2010-03-22 18:44:01 EDT
The fix for this requires the following API addition:

public interface OverrideContainer
	extends JpaContextNode
{
	interface Owner
	{
		...
		
		Iterator<String> allOverridableNames();
		
		...
	}
}


and the following API interface extensions:

public interface AttributeOverride2_0
	extends AttributeOverride
{
	/**
	 * Property string associated with changes to the mapped by relationship
	 */
	final String MAPPED_BY_RELATIONSHIP_PROPERTY = "mappedByRelationship";
	
	/**
	 * Return whether this attribute override is mapped by a relationship 
	 * (i.e. a relationship maps this attribute override, possibly in an entity overriding
	 *  an id or an embedded id overriding any attribute)
	 * N.B. - This might be several relationships (erroneously, of course)
	 */
	boolean isMappedByRelationship();
}

public interface EmbeddedIdMapping2_0
	extends EmbeddedIdMapping
{
	/**
	 * Property string associated with changes to the mapped by relationship
	 */
	final String MAPPED_BY_RELATIONSHIP_PROPERTY = "mappedByRelationship";
	
	/**
	 * Return whether this id is mapped by a relationship (i.e. a relationship maps this embedded id)
	 * N.B. - This might be several relationships (erroneously, of course)
	 */
	boolean isMappedByRelationship();
}

public interface IdMapping2_0
	extends IdMapping
{
	/**
	 * Property string associated with changes to the mapped by relationship
	 */
	final String MAPPED_BY_RELATIONSHIP_PROPERTY = "mappedByRelationship";
	
	/**
	 * Return whether this id is mapped by a relationship (i.e. a relationship maps this id)
	 * N.B. - This might be several relationships (erroneously, of course)
	 */
	boolean isMappedByRelationship();
}


It also requires UI changes in the form of uneditable checkboxes on id and embedded id mapping details pages to show the user whether the mapping has been mapped by a relationship (and so should therefore not specify any data information).
Comment 2 Paul Fullbright CLA 2010-03-23 13:22:02 EDT
Created attachment 162793 [details]
proposed patch
Comment 3 Neil Hauge CLA 2010-03-23 13:41:36 EDT
Requesting PMC approval for provisional API changes and a small UI change.  This is a bug and a blocking bug for a number of incorrect validation errors that are applied in this use case.  It is a must fix for the release to avoid these incorrect validation errors.  

The provisional API changes have been detailed in comment 1 and notice has been posted to the mailing list - http://dev.eclipse.org/mhonarc/lists/dali-dev/msg00939.html.

The UI change is noted at the bottom of comment 1.
Comment 4 Paul Fullbright CLA 2010-03-29 12:48:25 EDT
committed for M7
Comment 5 Karen Butzke CLA 2010-04-28 11:07:22 EDT
verified fixed in WTP build I-3.2.0-20100427043043