问题
Following this link
I would like to use OneToMany instead ManyToMany annotation, having middle class with composite key in it using Ebean. I have this error:
java.lang.RuntimeException: Error reading annotations for models.SoftwareTagPk
This is my SoftwareTagPk class:
@Embeddable
public class SoftwareTagPk implements Serializable {
@ManyToOne
private Tag tag;
@ManyToOne
private Software software;
...
}
And SoftwareTag class:
@Entity
public class SoftwareTag extends Model {
@EmbeddedId
private SoftwareTagPk pk = new SoftwareTagPk();
@Transient
public Tag getTag() {
return pk.getTag();
}
public void setTag(Tag aTag) {
pk.setTag(aTag);
}
@Transient
public Software getSoftware() {
return pk.getSoftware();
}
public void setSoftware(Software aSoftware) {
pk.setSoftware(aSoftware);
}
}
Also in logs:
Error with association to [class models.Tag] from [models.SoftwareTagPk.tag]. Is class models.Tag registered?
How to fix it?
回答1:
To make this code work you have to do:
- In your
SoftwareTagPk
class put only id's of Tag and Software - Move
@ManyToOne
relations toSoftwareTag
class - Add
@JoinColumn
annotations with attributesupdatable
andinsertable
set to false. - Override setters
setTag
andsetSoftware
inSoftwareTag
class. In these setters you will rewrite id's to composite key.
Main idea of this solution is that SoftwareTag
has composite key and @ManyToOne
relations and they are mapped to the same collumns.
This is the code:
Tag.java
@Entity
public class Tag extends Model {
@Id
private Integer id;
@OneToMany(mappedBy="tag")
public List<SoftwareTag> softwareTags;
public Integer getId() {
return id;
}
public void setId(Integer aId) {
id=aId;
}
public static Finder<Integer,Tag> find = new Finder<Integer,Tag>(
Integer.class, Tag.class
);
}
Software.java
@Entity
public class Software extends Model {
@Id
private Integer id;
@OneToMany(mappedBy="software")
public List<SoftwareTag> softwareTags;
public Integer getId() {
return id;
}
public void setId(Integer aId) {
id=aId;
}
}
SoftwareTag.java
@Entity
public class SoftwareTag extends Model {
SoftwareTag() {
pk = new SoftwareTagPk();
}
@EmbeddedId
private SoftwareTagPk pk = new SoftwareTagPk();
@ManyToOne
@JoinColumn(name = "tag_id", insertable = false, updatable = false)
private Tag tag;
@ManyToOne
@JoinColumn(name = "software_id", insertable = false, updatable = false)
private Software software;
public Tag getTag() {
return tag;
}
public void setTag(Tag aTag) {
tag = aTag;
pk.tag_id = aTag.getId();
}
public Software getSoftware() {
return software;
}
public void setSoftware(Software aSoftware) {
software = aSoftware;
pk.software_id = aSoftware.getId();
}
}
SoftwareTagPk.java
@Embeddable
public class SoftwareTagPk implements Serializable {
public Integer tag_id;
public Integer software_id;
@Override
public int hashCode() {
return tag_id + software_id;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
SoftwareTagPk pk = (SoftwareTagPk)obj;
if(pk == null)
return false;
if (pk.tag_id.equals(tag_id) && pk.software_id.equals(software_id)) {
return true;
}
return false;
}
}
来源:https://stackoverflow.com/questions/15593978/error-reading-annotations-with-composite-key-in-ebean