Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » JPA 2.0 @EmbeddedId mappings: bug with @MapsId in single-column identifying relationship?
JPA 2.0 @EmbeddedId mappings: bug with @MapsId in single-column identifying relationship? [message #669746] Wed, 11 May 2011 07:26 Go to next message
Karsten Wutzke is currently offline Karsten Wutzke
Messages: 112
Registered: July 2009
Senior Member
Hello,

I have the following simple design:

http://www.kawoolutions.com/media/countries-zips.png

Here the DDL:

CREATE TABLE Countries (
  id INTEGER NOT NULL,
  iso_code CHAR(2) NOT NULL,
  PRIMARY KEY (id),
  UNIQUE (iso_code));

CREATE TABLE Zips (
  country_code CHAR(2) NOT NULL,
  code VARCHAR(10) NOT NULL,
  PRIMARY KEY (country_code, code),
  CONSTRAINT zips_countries_fk
    FOREIGN KEY (country_code)
    REFERENCES Countries (iso_code)
    ON DELETE NO ACTION
    ON UPDATE CASCADE);

The Countries table has an ID as PK. Zips has a multi-column PK and uses a single-column reference to a non-PK column (alternative unique key) iso_code. The latter is the specialty of this design.

EclipseLink has problems mapping them with the following entity classes:

@Entity
@Table(name = "Countries")
public class Country implements Serializable
{
    @Id
    @Column(name = "id")
    private Integer id;

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

    ...
}

@Entity
@Table(name = "Zips")
public class Zip implements Serializable
{
    @EmbeddedId
    private ZipId embeddedId;

    @MapsId(value = "countryCode") // outcomment @MapsId to make JPA 1.0 @EmbeddedId work
    @ManyToOne
    @JoinColumn(name = "country_code", referencedColumnName = "iso_code")
    private Country country;
    
    ...
}

@Embeddable
public class ZipId implements Serializable
{
    @Column(name = "country_code", insertable = false, updatable = false)
    private String countryCode;

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

    ...
}

Using the entity manager to retrieve a single ZIP entity:
Zip zi = em.find(Zip.class, new ZipId("DE", "64846"));

Stack trace:

Entity manager created!

Loaded country = tld.geoareas.model.Country@5bf02b85[id=1,isoCode=AF]
Exception in thread "main" java.lang.IllegalArgumentException: You have provided an instance of an incorrect PK class for this find operation.  Class expected : class java.lang.Integer, Class received : class java.lang.String.
    at org.eclipse.persistence.internal.jpa.CMP3Policy.createPrimaryKeyFromId(CMP3Policy.java:215)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.findInternal(EntityManagerImpl.java:695)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.find(EntityManagerImpl.java:617)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.find(EntityManagerImpl.java:496)
    at tld.geoareas.Main.main(Main.java:38)

I know the JPA doesn't officially support non-PK relationships, but EclipseLink has no problems with mapping these in JPA 1.0 @IdClass syntax and more importantly without the JPA 2.0 @MapsId annotation (basically resulting in JPA 1.0 @EmbeddedId syntax).

So EclipseLink should technically be able to handle this non-JPA mapping but it doesn't.

There are two possibilities now:

1. I'm using the @MapsId annotation incorrectly
2. It's a bug

I know EL should expect a PK column here, but again since it correctly maps other non-PK relationship syntaxes mentioned above, this one should be supported as well.

So, is this an EclipseLink bug? Or is it just the JPA 2.0 spec being more restrictive than JPA 1.0? (just comment the @MapsId annotation and see for yourself)

I have put up an SSCCE here (JavaSE, EL 2.2.0 nightly, HSQLDB): http://www.kawoolutions.com/media/el-sic-idrel-jpa2embid.zip

I'd be glad if the someone (EL maintainers?) could have a look at this problem.

Thanks
Karsten

[Updated on: Sun, 15 May 2011 06:21]

Report message to a moderator

Re: JPA 2.0 @EmbeddedId mappings: bug with @MapsId? [message #670050 is a reply to message #669746] Thu, 12 May 2011 10:03 Go to previous messageGo to next message
James Sutherland is currently offline James Sutherland
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

Remove the @MapsId and it should work. Putting @MapsId on the @ManyToOne makes no sense, because it does not map the Id.



James : Wiki : Book : Blog : Twitter
Re: JPA 2.0 @EmbeddedId mappings: bug with @MapsId? [message #670186 is a reply to message #670050] Thu, 12 May 2011 20:45 Go to previous messageGo to next message
Karsten Wutzke is currently offline Karsten Wutzke
Messages: 112
Registered: July 2009
Senior Member
@James:

Of course removing the @MapsId makes it work. I wrote this! See the comment at the @MapsId...

The @MapsId is placed correctly in context with the @ManyToOne, see http://www.objectdb.com/api/java/jpa/MapsId

BTW the question was whether this is bug in EclipseLink (as I highly suspect) or not. Finding a working solution was not asked.

Anyone else? I'll create a bug report otherwise.

Karsten

[Updated on: Thu, 12 May 2011 20:46]

Report message to a moderator

Re: JPA 2.0 @EmbeddedId mappings: bug with @MapsId? [message #670302 is a reply to message #670186] Fri, 13 May 2011 09:04 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris Delahunt
Messages: 1016
Registered: July 2009
Senior Member
Hello Karsten,

Its not strictly a bug as the JPA specification demands foreign keys point to primary keys. EclipseLink support works, but in this case you are setting it up to use the JPA 2.0 derrived ID feature. The policy used to convert the JPA primary key into an EclipseLink recognizable identifier was coded using the specifications requirements that the relationship would point to the entities primary key, which is why you get the exception. You will only run into this problem when using the entities primay key class. This means you can work around this by not using find, or by passing in a collection of values to the find method instead of the ZipId class. ie a vector containing an Integer and String.

Please file a bug to have this requirement loosened.

Best Regards,
Chris
Re: JPA 2.0 @EmbeddedId mappings: bug with @MapsId? [message #670417 is a reply to message #670302] Fri, 13 May 2011 20:18 Go to previous messageGo to next message
Karsten Wutzke is currently offline Karsten Wutzke
Messages: 112
Registered: July 2009
Senior Member
Hello Chris,

I'm not sure if I really got your point (or vice versa). The mappings I posted work when outcommenting the @MapsId annotation and EL fails when the @MapsId(value = "countryCode") is present. It doesn't make any sense, does it?

Would it help to provide an SSCCE here?

The use of the @MapsId annotation basically turns the mapping into a JPA 2.0 derived identity, but why should the newer JPA 2.0 mapping type be more restrictive than the old (again given the fact that EL correctly handles the mappings without the @MapsId annotation)?

Even though the JPA doesn't support relationships to non-PK columns doesn't mean they are forbidden in derived identities. It's up to EL to implement this as an optional feature. EL currently handles non-PK relationships pretty well, so why not support them in derived identities, too? The technology is already there I'd think.

For your reference please also see http://www.kawoolutions.com/Technology/JPA,_Hibernate,_and_C o./Relationships_to_Non-Primary_Key_Columns for a case study of relationships to non-PK columns. (it's pretty new and there will likely be things to be corrected)

Karsten

[Updated on: Sun, 15 May 2011 14:44]

Report message to a moderator

Re: JPA 2.0 @EmbeddedId mappings: bug with @MapsId? [message #670655 is a reply to message #670417] Sun, 15 May 2011 06:34 Go to previous messageGo to next message
Karsten Wutzke is currently offline Karsten Wutzke
Messages: 112
Registered: July 2009
Senior Member
Where did my post go? I changed the original posting's title and now everything is gone!

Can anyone recover it?

Karsten
Re: JPA 2.0 @EmbeddedId mappings: bug with @MapsId? [message #670998 is a reply to message #670417] Mon, 16 May 2011 09:52 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris Delahunt
Messages: 1016
Registered: July 2009
Senior Member
Hello Karsten,

As mentioned, JPA requires the foreign key->primary key, and EclipseLink uses this restriction in determining what the Primary key class should look like when you are using the Derrived Id JPA 2.0 feature. As mentioned, fill a bug to have this behavior changed if you wish. It was done likely because the primary key class is entirely a JPA construct - EclipseLink internally uses collections of values as the primary key, not a pk class.

The restriction is only in the CMP3Policy class, which is mostly only used for the em.find method to convert the JPA pk class into a vector of values. If you can avoid it, you will not have any problems. Or, you can use the em.find passing in a vector of values instead of your JPA pk class, avoiding the conversion.

Regards,
Chris

edit: The policy is not more restrictive. When specifying mapsId it uses the Derrived ID which means it must go to the reference class to get the value instead of using the value in the object like it would in JPA 1.0. This relationship traversal is what has the expectation that the field will be the primary key field. As mentioned, file a bug to have this changed.

[Updated on: Mon, 16 May 2011 09:55]

Report message to a moderator

Re: JPA 2.0 @EmbeddedId mappings: bug with @MapsId? [message #671069 is a reply to message #670998] Mon, 16 May 2011 13:00 Go to previous messageGo to next message
Karsten Wutzke is currently offline Karsten Wutzke
Messages: 112
Registered: July 2009
Senior Member
Thanks Chris for your explanations. Such in-depth information is always very helpful.

As a result of JPA 2.0 "derived identities" it appears to users of EclipseLink (and Hibernate) as if the JPA 2.0 mappings are always inferior when compared to the JPA 1.0 mappings (both @IdClass or @EmbeddedId/@MapsId derived identies). It can really confuse negatively, as anyone would expect the newer version to be more functional.

Please see the results of my test case about using relationships to non-primary key columns in PKs or not here (scroll to the end the see the resulting JPA 2.0 mappings not work overall):

http://www.kawoolutions.com/Technology/JPA,_Hibernate,_and_C o./Relationships_to_Non-Primary_Key_Columns

I did report the bug/enhancement here:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=345839

Best regards
Karsten
Re: JPA 2.0 @EmbeddedId mappings: bug with @MapsId? [message #671082 is a reply to message #671069] Mon, 16 May 2011 13:48 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris Delahunt
Messages: 1016
Registered: July 2009
Senior Member
Hello Karsten,

I don't believe they are inferior, more that they are designed to support a particular use case that doesn't match what you need. They work well enough if your model had foreign keys to primary keys as the JPA 1.0 spec requires. The new derrived ID feature is built on that requirement, so should not be seen as adding any new restrictions. I am not sure EclipseLink needed to build off that restriction, but I'm sure will be looked at in the bug.

Please remember though that using a foreign key to something other than the primary key may end up affecting your performance. While it is difficult to say what the costs will be, Entities are usually cached on their primary keys, so references to other fields will need to go to the database to be resolved efficiently. You might want to take this into consideration when picking the fields to reference in your model as it might make scaling more difficult later on.

Best Regards,
Chris
Re: JPA 2.0 @EmbeddedId mappings: bug with @MapsId? [message #769623 is a reply to message #671082] Thu, 22 December 2011 07:30 Go to previous messageGo to next message
Karsten Wutzke is currently offline Karsten Wutzke
Messages: 112
Registered: July 2009
Senior Member
I filed a RFE some time ago here:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=345839

Please have a look at it.

I have also entered a more lengthy description of the problem at the official JPA expert panel as a RFE, so chances are you will also receive it.

I'd be glad to see relationships to non-primary key columns in derived identities in the future!

See here for a test case:

http://www.kawoolutions.com/Technology/JPA,_Hibernate,_and_Co./Relationships_to_Non-Primary_Key_Columns

Thanks
Karsten
Re: JPA 2.0 @EmbeddedId mappings: bug with @MapsId? [message #769624 is a reply to message #671082] Thu, 22 December 2011 07:30 Go to previous message
Karsten Wutzke is currently offline Karsten Wutzke
Messages: 112
Registered: July 2009
Senior Member
I filed a RFE some time ago here:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=345839

Please have a look at it.

I have also entered a more lengthy description of the problem at the official JPA expert panel as a RFE, so chances are you will also receive it.

I'd be glad to see relationships to non-primary key columns in derived identities in the future!

See here for a series of test cases:

http://www.kawoolutions.com/Technology/JPA,_Hibernate,_and_Co./Relationships_to_Non-Primary_Key_Columns

Thanks
Karsten

[Updated on: Thu, 22 December 2011 07:37]

Report message to a moderator

Previous Topic:Order by primary key as a associated entity.
Next Topic:Command line EclipseLink
Goto Forum:
  


Current Time: Sat Jul 26 09:29:57 EDT 2014

Powered by FUDForum. Page generated in 0.02642 seconds