Eclipse error on mapping with @EmbeddedId
Asked Answered
M

5

14

I have an entity with composite key so I use the @Embeddable and @EmbeddedId annotations. Embeddable class looks like this :

@Embeddable
public class DitaAdminAccountSkillPK implements Serializable {

  @ManyToOne
  @JoinColumn(name = "admin_id")
  private DitaAdmin admin;

  @ManyToOne
  @JoinColumn(name = "account_id")
  private DitaAccount account;

  //constructor, getters, setters...
}

And the entity that uses it :

@Entity
public class DitaAdminAccountSkill {

  @EmbeddedId
  private DitaAdminAccountSkillPK id;

  //constructor, getters, setters...
}

Now I want to map the entity in another entity like this :

@OneToMany(fetch = FetchType.LAZY, mappedBy = "id.admin")
private List<DitaAdminAccountSkill> accountSkills;

Notice the mappedBy = "id.admin" which refers to admin field in DitaAdminAccountSkillPK using the id field of DitaAdminAccountSkill.

This compiles and runs just fine. However, in eclipse there is an error displayed that says : In attribute 'accountSkills', the "mapped by" value 'id.admin' cannot be resolved to an attribute on the target entity.

Note that this is a JPA Problem meaning the JPA facet is complaining. Now, I know I could use @IdClass instead but I am just wondering why does it think its an error. Or maybe I do something terribly wrong ?

Membership answered 24/8, 2012 at 8:55 Comment(0)
E
26

According to section 11.1.15 of the JPA 2.0 specification: Relationship mappings defined within an embedded id class are not supported. However, this might be supported by the JPA implementation you're using, even if it's not officially supported by the standard itself.

If this is the case here, you might want to turn off validation for this in Eclipse under Window -> Preferences -> Java Persistence -> JPA -> Errors/Warnings -> Attributes -> Cannot resolve attribute name.

Elanorelapid answered 24/8, 2012 at 11:34 Comment(3)
Is there a way to do this that is supported by JPA 2.0 spec?Boggart
Answered my own question. Section 2.4.1.3 of the JPA 2.0 spec (found here) lists a number of very useful examples for this scenario. My solution was to use @EmbeddedID along with @MapsId.Boggart
Found JPA 2.0 friendly solution: #10078724Onagraceous
C
7

In my case, the problem was not resolved until I set the following to Ignore:

Project Facets > JPA > Errors/Warnings > Type > Mapped Java Class is a member class
Chorizo answered 24/10, 2014 at 2:15 Comment(0)
B
5

Thought I would post the solution that I found which is compliant with the JPA 2.0 specification and appears to function the same way.

First off, the JPA 2.0 specification can be found here: JSR-000317 Persistence Specification for Eval 2.0 Eval. The relevant section would be 2.4.1 "Primary Keys Corresponding to Derived Identities"

Here is an example using the classes you specified:

Embedded Id Class:

@Embeddable
public class DitaAdminAccountSkillPK implements Serializable {

    //No further annotations are needed for the properties in the embedded Id.

    //Needs to match the type of the id of your DitaAdmin object. I added 'Id' to the end of the property name to be more explicit.
    //Making the assumption here that DitaAdmin has a simple Integer primary key.
    private Integer adminId;

    //Needs to match the type of the id of your DitaAccount object. I added 'Id' to the end of the property name to be more explicit.
    //Making the assumption here that DitaAccount has a simple Integer primary key.
    private Integer accountId;


    //I'm adding a third property to the primary key as an example
    private String accountName;

    //constructor, getters, setters...

    //hashCode() and equals() overrides
}

"Dependent" Entity Class:

@Entity
public class DitaAdminAccountSkill {

    @EmbeddedId
    //Any overrides to simple Id properties should be handled with an attribute override
    @AttributeOverride(name = "accountName", column = @Column(name = "account_name"))
    private DitaAdminAccountSkillPK id;

    //MapsId refers to the name of the property in the embedded Id
    @MapsId("adminId")
    @JoinColumn(name="admin_id")
    @ManyToOne
    private DitaAdmin admin;

    @MapsId("accountId")
    @JoinColumn(name="account_id")
    @ManyToOne
    private DitaAccount account;

    //constructor, getters, setters...
}

"Parent" Entity class:

public class DitaAdmin {

    @Id
    private Integer id;

    //...

    //Now your mappedBy attribute can refer to the admin object defined on DitaAdminAccountSkill which is also part of the Primary Key
    @OneToMany(fetch = FetchType.LAZY, mappedBy="admin")
    private List<DitaAdminAccountSkill> accountSkills;

    //...
}
Boggart answered 22/1, 2013 at 21:22 Comment(1)
With these both options (mappedBy="id.admin" or mappedBy="admin").. when I try to map "Non Lazy Collection", I will get following error. Error: resql.util.PSQLException: ERROR: column workflowst0_.stepseqno does not exist . Please look at #23313451 . Thanks in advance.Ojibwa
P
3

Before trying any of the previous solutions check first your persistence.xml and ensure that either exclude-unlisted-classes is set to true or that all your mapped classes are listed within your persistence-unit.

Pompei answered 16/3, 2015 at 20:59 Comment(0)
P
1

Preferences -> Java Persistence -> JPA -> Errors/Warnings -> Attribute -> Embedded ID classes should not contain relationship mappings: (Ignore)

Piano answered 25/9, 2015 at 14:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.