Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 330593 - ValidationException: The @JoinColumns on the annotated element [field X] from the entity class [class Y] is incomplete
Summary: ValidationException: The @JoinColumns on the annotated element [field X] from...
Status: CLOSED INVALID
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows 7
: P3 critical (vote)
Target Milestone: ---   Edit
Assignee: Nobody - feel free to take it CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-11-18 13:00 EST by Karsten Wutzke CLA
Modified: 2022-06-09 10:35 EDT (History)
2 users (show)

See Also:


Attachments
SSCCE demonstrating the problem (1.51 MB, application/octet-stream)
2010-11-18 13:08 EST, Karsten Wutzke CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Karsten Wutzke CLA 2010-11-18 13:00:58 EST
EclipseLink fails mapping tables with ValidationException:

Caused by: Exception [EclipseLink-7220] (Eclipse Persistence Services - 2.2.0.v20101118-r8514): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The @JoinColumns on the annotated element [field subCompetition] from the entity class [class tld.rounds.model.Round] is incomplete. When the source entity class uses a composite primary key, a @JoinColumn must be specified for each join column using the @JoinColumns. Both the name and the referencedColumnName elements must be specified in each such @JoinColumn.
	at org.eclipse.persistence.exceptions.ValidationException.incompleteJoinColumnsSpecified(ValidationException.java:1775)
	at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor.getJoinColumnsAndValidate(MappingAccessor.java:557)
	at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor.getJoinColumns(MappingAccessor.java:500)
	at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ObjectAccessor.processOneToOneForeignKeyRelationship(ObjectAccessor.java:614)
	at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ObjectAccessor.processOwningMappingKeys(ObjectAccessor.java:667)
	at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ManyToOneAccessor.process(ManyToOneAccessor.java:110)
	at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processOwningRelationshipAccessors(MetadataProject.java:1282)
	at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processStage3(MetadataProject.java:1495)
	at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.processORMMetadata(MetadataProcessor.java:484)
	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

I have a table Rounds with a single-column ID which references another table SubCompetitions which has a two-column primary key (which again is made up of two single-column FKs to the tables TeamTypes and Competitions).

When mapping the Rounds entity class to:

@Entity
@Table(name = "Rounds")
public class Round implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @Column(name = "name")
    private String name;

    @ManyToOne
    @JoinColumn(name = "parent_id", referencedColumnName = "id")
    private Round round = null;

    @ManyToOne
    @JoinColumns(value = {@JoinColumn(name = "competition_name"), @JoinColumn(name = "team_type_code")}) // this should work, because both columns' names equal!
    //@JoinColumns(value = {@JoinColumn(name = "competition_name", referencedColumnName = "competition_name"), @JoinColumn(name = "team_type_code", referencedColumnName = "team_type_code")})
    private SubCompetition subCompetition = null;

    ...
}

the ValidationException occurrs. The @JoinColumns annotation on subCompetition appears to be correct, because both the referencing and referenced column names are equals, making referencedColumnName = ? redundant.

To get rid of the problem, uncomment the alternative @JoinColumns annotation.

Please see the SSCCE attached (JavaSE, HSQLDB, EL, Ant). Just enter "ant run", that shall do it.
Comment 1 Karsten Wutzke CLA 2010-11-18 13:08:04 EST
Created attachment 183407 [details]
SSCCE demonstrating the problem

The SSCCE was tested with EclipseLink nightly from 2010-11-18 R8514. Due to the file size I removed eclipselink.jar from its local lib dir. Please copy a current version there.
Comment 2 Karsten Wutzke CLA 2010-11-18 13:12:23 EST
Note that the error message

When the source entity class uses a composite primary key, a
@JoinColumn must be specified for each join column using the @JoinColumns. Both
the name and the referencedColumnName elements must be specified in each such
@JoinColumn.

is plain wrong here and may confuse. The source entity class doesn't have a composite primary key.

Furthermore note that referencedColumnName is only needed if at least one column name is different (in case of a composite primary key).
Comment 3 Karsten Wutzke CLA 2010-11-19 12:33:49 EST
I found the pitfall:

http://download.oracle.com/javaee/5/api/javax/persistence/JoinColumn.html#referencedColumnName%28%29

It says:

"... Default (only applies if single join column is being used): The same name as the primary key column of the referenced table."

This means, that the referencedColumnName may *never* be omitted with composite/multi-column @JoinColumns declarations.

Hmmm. It isn't clear why this has to be that way, but you can't change it. JPA could do better here by only requiring referencedColumnName if at least one column in the multi-column names are different.

Anyway, you can mark this as bogus now...
Comment 4 Karsten Wutzke CLA 2010-11-19 18:28:46 EST
Or rather

http://download.oracle.com/javaee/5/api/javax/persistence/JoinColumns.html

"When the JoinColumns annotation is used, both the name and the referencedColumnName elements must be specified in each such JoinColumn annotation."
Comment 5 Tom Ware CLA 2010-12-03 08:34:10 EST
Closing based on comments above.
Comment 6 Eclipse Webmaster CLA 2022-06-09 10:35:53 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink