Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 336879 - @ManyToOne pointed at a column from a @MappedSuperclass fails
Summary: @ManyToOne pointed at a column from a @MappedSuperclass fails
Status: RESOLVED FIXED
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: Macintosh Mac OS X - Carbon (unsup.)
: P3 major with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: Guy Pelletier CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-02-10 16:36 EST by Laird Nelson CLA
Modified: 2022-06-09 10:08 EDT (History)
6 users (show)

See Also:


Attachments
A test case that regrettably does not reproduce the bug yet. (4.51 KB, application/octet-stream)
2011-02-11 10:10 EST, Laird Nelson CLA
no flags Details
A test case that DOES reproduce the bug. (5.20 KB, application/x-gzip)
2011-02-11 11:24 EST, Laird Nelson CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Laird Nelson CLA 2011-02-10 16:36:34 EST
Build Identifier: Eclipse Persistence Services - 2.2.0.v20110203-r8920

A MappedSuperclass has a code field with a @Basic mapping.

An entity class extends it and adds no new fields.

Another entity class has a @ManyToOne relationship with that entity.  This field is named donationTypeCode.  Its referencedColumnName attribute says "code" (the column that is virtually inherited by the first entity from the @MappedSuperclass).

EclipseLink says there is no target:

Exception [EclipseLink-7333] (Eclipse Persistence Services - 2.2.0.v20110203-r8920): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The reference column name [code] mapped on the element [field donationTypeCode] does not correspond to a valid field on the mapping reference.

Reproducible: Always

Steps to Reproduce:
From my email to the users list:

Here's what I've got.  In all cases I am not the class author.

A @MappedSuperclass named AbstractType, which, among other things, has this defined:

  @Basic(optional = false)
  @Column(name = "code", length = 8, unique = true, nullable = false)
  private String code;

Then I have a class that inherits from this @MappedSuperclass and which defines no additional fields.  Its name is DonationTypeEntity.

Finally, I have the offender--an entity named AcknowledgeTypeEntity with a @ManyToOne in it like this:

    @ManyToOne(optional = false, targetEntity = DonationTypeEntity.class)
    @JoinColumn(name = "donation_type_code", referencedColumnName = "code", nullable = false)
    private DonationType donationTypeCode;

It would appear that EclipseLink is complaining about this perfectly valid mapping.
Comment 1 Laird Nelson CLA 2011-02-10 17:24:05 EST
You may want to comment on http://java.net/jira/browse/GLASSFISH-15625, which is Glassfish's umbrella bug for integrating EclipseLink 2.2.0.
Comment 2 Laird Nelson CLA 2011-02-11 09:24:28 EST
I'm beginning to feel sheepish here because my test case in isolation (which I will attach) cannot reproduce this so far. I have several more iterations to go for it to fully match my production environment, however.
Comment 3 Tom Ware CLA 2011-02-11 09:34:20 EST
I am having the same issue.  Here's what I've got:

@MappedSuperclass
public class Asuper {
   
    @Basic(optional = false)
    @Column(name = "code", length = 8, unique = true, nullable = false)
    private String code;

    @Id
    private int id;
    
etc...


@Entity
public class A extends Asuper{
}

@Entity
public class B {

    @Id
    private int id;
    
    @ManyToOne(optional = false, targetEntity = A.class)
    @JoinColumn(name = "donation_type_code", referencedColumnName = "code", nullable = false)
    private A donationTypeCode;

etc...


Test
----
    public static void main(String[] args){
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("TestAbstractTargetManyToOne");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        A a = new A();
        a.setId(1);
        a.setCode("1");
        
        B b = new B();
        b.setId(1);
        b.setDonationTypeCode(a);
        
        em.persist(a);
        em.persist(b);
        
        em.getTransaction().commit();
Comment 4 Laird Nelson CLA 2011-02-11 10:06:10 EST
In case it matters, in my production environment there are a few extra wrinkles.

Each entity implements an interface.

Each level of the API is in its own jar.  So the interfaces are in one jar, the entities are in another.

The mapped superclass in question is from one jar; the entity that extends it is from another.

The unit test that is running has these jars on the classpath, but the persistence.xml lists individual classes.

I will attach my test case, which does NOT showcase this bug yet, but perhaps you'll see something I don't.
Comment 5 Laird Nelson CLA 2011-02-11 10:10:48 EST
Created attachment 188781 [details]
A test case that regrettably does not reproduce the bug yet.

This test case passes.  However it does not yet fully reflect my production environment.

In my production environment, MappedSuperclassInterface, MappedSuperclass, and the two entity classes are in separate jars.

All these jars are present on the classpath at unit test time, but are referenced from the persistence.xml using the <class> element.

I will keep iterating this test case to fully reproduce the error; I wanted to get this out there in case anyone else can build on it.
Comment 6 Laird Nelson CLA 2011-02-11 11:24:35 EST
Created attachment 188791 [details]
A test case that DOES reproduce the bug.

This test case reproduces the bug.

In my production environment, there is a (mysterious) @AttributeOverride present on the target entity.  It actually doesn't override anything (i.e. it sets the length to 8, but the length was already declared as being 8).

However the presence of this annotation causes the failure.

I have put the @AttributeOverride on TargetEntity.java exactly as it is present in our codebase.  I would be curious to know if this is a legally specified override, or if more boilerplate is required.
Comment 7 Laird Nelson CLA 2011-02-11 11:49:59 EST
The only remaining mystery is that this @AttributeOverride has been present in our codebase since August 2010, and ran fine with EclipseLink version 2.0.1.

But I cannot make the test case that is attached pass, even if I downgrade EclipseLink to 2.0.1.
Comment 8 Tom Ware CLA 2011-02-11 11:57:54 EST
It looks like:

@AttributeOverride(name="code", column=@Column(length=8))

Causes the name of the column to be defaulted.  It ends up defaulted to
uppercase in 2.2.  In our trunk stream this issue does not exist.

There are two workarounds:

1. specify the name on the column definition

@AttributeOverride(name="code", column=@Column(name="code", length=8))

2. Specify the following persistence unit property:

<property name="eclipselink.jpa.uppercase-column-names" value="true"/>


More to come...
Comment 9 Laird Nelson CLA 2011-02-11 12:06:04 EST
(In reply to comment #8)
> There are two workarounds:
> 
> 1. specify the name on the column definition
> 
> @AttributeOverride(name="code", column=@Column(name="code", length=8))

Will do.  A question: is this required by the JPA spec, or is it just good practice?
Comment 10 Tom Ware CLA 2011-02-11 13:10:28 EST
I have not been able to find a specific reference to this case in the specification.  In the absence of a specific reference, I have to assume that any @Column specified in an AttributOverride should be defaulted in the same way as an other column.

I suspect the reason you don't see this issue on other providers is that they handle the case of the default differently and as a result figure out that the columns are the same.

In any case, our trunk stream does not show this failure, so our plan will be to backport the change that resolves this issue.

In the meantime, your best bet is to use one of the workarounds.
Comment 11 John Manko CLA 2011-03-28 14:27:18 EDT
Laird, Tom,

I came across this same issue with @Column on a standard @ManyToOne relationship.  After I found this bug report, I decided to write a post detailing it.  


http://www.johnmanko.com/blog/2011/03/27/unexpected-problems-with-glassfish-v3-1-update-part-1/


I believe that the article's technical accuracy is correct, and I wanted to share with everyone the breakdown of the problem.  If it is not, I'll make whatever changes are required.  I hope that it's ok for me to post this link, but delete feel free to delete it or contact me if it's not.  Thanks, and I hope this helps others.  I spend many hours trying to resolve this problem, and I hope other won't have to.
Comment 12 Guy Pelletier CLA 2011-07-12 12:12:23 EDT
Marking this as resolved as the fix for bug 343632 was back ported and it will correct this exception.
Comment 13 Eclipse Webmaster CLA 2022-06-09 10:08:29 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink