1

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?

4

1 回答 1

2

要使此代码正常工作,您必须执行以下操作:

  1. 在你的SoftwareTagPk课堂上只放标签和软件的 id
  2. @ManyToOne关系移动到SoftwareTag
  3. 添加@JoinColumn带有属性的注释updatableinsertable设置为 false。
  4. 覆盖二传手setTag和课堂setSoftwareSoftwareTag在这些设置器中,您将 id 重写为复合键。

该解决方案的主要思想是SoftwareTag具有复合键和@ManyToOne关系,并且它们被映射到相同的列。

这是代码:

标签.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
    ); 
} 

软件.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;
    }
}

软件标签.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();
    }
}

软件标签库.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;
    }
}
于 2014-12-01T22:52:36.473 回答