【问题标题】:Many-to-many relation returns empty collection多对多关系返回空集合
【发布时间】:2019-06-22 20:05:07
【问题描述】:

我正在尝试创建两个实体,它们之间具有多对多关系。第一个实体是 Person,以 PID 作为主键,第二个实体是 Serie,以 SID 作为主键。在数据库中有一个表TJV_5_SERIE_2_PERSON,它代表了这些实体之间的多对多关系。

tables in database

问题是当我检索任何实体时,使用 @ManyToMany 注释的 Collection 始终为空。所以我假设我在代码中搞砸了一些东西,这解释了为什么我的多对多关系不起作用。

我通过生成(在 Netbeans 9.0 中)“来自实体类的 Restful Web 服务”来检索这两个实体。这样我就可以使用这些服务成功检索所有属性,但带有 @ManyToMany 注释的 Collection 始终为空。

任何想法为什么它不值得赞赏。这是第一次尝试,请原谅我的任何愚蠢错误。

人物类:

@Entity
@Table(name = "TJV_5_PERSON")
@XmlRootElement
public class Person implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "PID")
    private Integer id;

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

    @ManyToMany()
    @JoinTable(
        name = "TJV_5_SERIE_2_PERSON",
        joinColumns = @JoinColumn(name = "PID", referencedColumnName = "PID"),
        inverseJoinColumns = @JoinColumn(name = "SID", referencedColumnName = "SID")
    )
        // always empty
    private Collection<Serie> favourites = new ArrayList<Serie>();

    public Person() {
    }

    public Person(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @XmlTransient
    public Collection<Serie> getFavourites() {
        return favourites;
    }

    public void setFavourites(Collection<Serie> favourites) {
        this.favourites = favourites;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 31 * hash + Objects.hashCode(this.id);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Person other = (Person) obj;
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "Person{" + "id=" + id + ", name=" + name + ", favourites=" + favourites + '}';
    }

}

意甲类:

@Entity
@Table(name = "TJV_5_SERIE")
@XmlRootElement
public class Serie implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "SID")
    private Integer id;

    @Column(name = "STITLE")
    private String title;

    // always empty
    @ManyToMany(mappedBy = "favourites")
    private Collection<Person> fans = new ArrayList<Person>();

    public Serie() {
    }

    public Serie(Integer id, String title) {
        this.id = id;
        this.title = title;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    @XmlTransient
    public Collection<Person> getFans() {
        return fans;
    }

    public void setFans(Collection<Person> fans) {
        this.fans = fans;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 67 * hash + Objects.hashCode(this.id);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Serie other = (Serie) obj;
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "Serie{" + "id=" + id + ", title=" + title + ", fans=" + fans + '}';
    }

}

【问题讨论】:

  • 在 ORM 代码中,对象模型应该是规则的。表中的id 列是一种性能黑客,而不是对象模型的固有部分。对象比较应该基于区分个体的建模属性。如果您没有表明模型不完整的此类属性。

标签: java rest jakarta-ee


【解决方案1】:

我不是 100% 确定,但由于 Serie.class 方法上方的 @XMLTransiet 注释,您可能无法检索到任何结果

@XmlTransient
public Collection<Person> getFans() {
    return fans;
}

尝试查看文档https://docs.oracle.com/javaee/6/api/javax/xml/bind/annotation/XmlTransient.html 或相关帖子Hide an entity variable from xml message - @XmlTransient not working

【讨论】:

  • 在 Serie.class 中的 getFans() 中删除 @XmlTransient 注释仅适用于 Serie.class。方法 getFans() 开始返回正确的结果。然而,多对多的另一面,Person.class 的 Collection 仍然是空的。非常感谢你,至少有些东西在起作用。
【解决方案2】:

另一个问题是两个对应的@ManyToMany 表之间的级联数据。这意味着您有交集,当您使用某种类型的级联时,数据会自动出现在此表中,但您需要发送 POST 请求。这意味着在您的服务类层中,您可以创建一个负责创建 Person 的方法并将一个 Serie 分配给这个作为外键的 Person 对象。关于级联的文章在这里 :) https://vladmihalcea.com/a-beginners-guide-to-jpa-and-hibernate-cascade-types/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-09
    • 2019-11-27
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 2018-01-24
    相关资源
    最近更新 更多