I'm currently struggling with the right mapping annotations for a scenario using a composite Primary Key Class. First, what I am trying to achieve in words:
I have 2 classes: group and FieldAccessRule. A Group can have many FieldAccessRules, while a FieldAccessRule only has ONE Group assigned. Modling this is not a problem so far (simplified):
public class Group{
...
@OneToMany(mappedBy = "group")
private Set<FieldAccessRule> fieldAccessRules;
...
}
and for the FieldAccessRule:
public class FieldAccessRule {
...
@ManyToOne
@JoinColumn(name = "group_id")
private Group group;
...
}
Now, I decided to use a Composite PK for the FieldAccessRule, because a Rule should be unique for ONE Group and ONE Field. It looks like this:
@Embeddable
public class FieldAccessRulePK implements Serializable{
private String fieldKey;
private Group group;
...
}
And ofc. the FieldAccessRule needs to change to
public class FieldAccessRule {
...
@EmbeddedId
private FieldAccessRulePK fieldAccessRulePK;
...
}
How do I create the right Mapping for the FieldAccessRuleSet of Group now? Doing it like this, I get :
In attribute 'fieldAccessRules', the "mapped by" value 'group' cannot be resolved to an >attribute on the target entity.
Whats the right way of creating the mapping from Group to A PART of the PrimaryKey?
Edit: I know found out, that using
public class Group{
...
@OneToMany(mappedBy = "fieldAccessRolePK.group")
private Set<FieldAccessRule> fieldAccessRules;
...
}
is EXACTLY working as expected. It compiles fine, it creates the DB fine and after loading a group with predefined Roles, they are available as expected.
However, Eclipse still says
In attribute 'fieldAccessRules', the "mapped by" value 'fieldAccessRulePK.group' cannot be resolved to an attribute on the target entity.
Im not sure, if it's good to ignore Error and "assume" everythings fine... (I found a post, where it has been said, that a mapping of the pattern attr1.attr2 is supported by Hibernate but not JPA-confirm.)
In your code, EntityManager
cannot resolve mappedBy
attribute fieldAccessRulePK.group
.
Reason
EntityManager
assume that FieldAccessRule
entity have an attribute name with fieldAccessRulePK.group during the FieldInjection
.
According to Java Naming Variables Rule, you cannot name fieldAccessRulePK.group
by using characters dot > '.'
Java Naming Variables Rule Reference
All variable names must begin with a letter of the alphabet, an underscore ( _ ), or a dollar sign ($). The rest of the characters may be any of those previously mentioned plus the digits 0-9. The convention is to always use a letter of the alphabet. The dollar sign and the underscore are discouraged.
One more thing:
Don't use group
instance in your FieldAccessRulePK
embeddable class. For more reference here.
Try as below :
@Embeddable
public class FieldAccessRulePK implements Serializable{
@Column(name = "FIELD_KEY")
private String fieldKey;
@Column(name = "GROUP_ID")
private String groupId;
}
public class FieldAccessRule {
@EmbeddedId
private FieldAccessRulePK id;
@ManyToOne
@JoinColumn(name = "GROUP_ID", referencedColumnName = "ID")
private Group group;
}
public class Group{
@OneToMany(mappedBy = "group")
private Set<FieldAccessRule> fieldAccessRules;
}
I've fixed a similar problem by modifying the mappedBy
attribute of the parent class (using dotted notation)
public class Group{
...
@OneToMany(mappedBy = "fieldAccessRulePK.group")
private Set<FieldAccessRule> fieldAccessRules;
...
}
and by keeping the annotations in the PK class:
@Embeddable
public class FieldAccessRulePK implements Serializable{
private String fieldKey;
@ManyToOne
@JoinColumn(name = "group_id")
private Group group;
...
}
来源:https://stackoverflow.com/questions/12952141/jpa-hibernate-onetomany-mapping-using-a-composite-primarykey