使用 Jersey 的 JAX-RS 的休眠资源类中具有连接表的多对一

2023-11-26

我正在使用 Jersey 实现 RESTful Web 服务。我使用 hibernate 与数据库(mySQL)进行通信。我的休眠资源类包括:

@Entity
public class Activity {

    @Id
    @GeneratedValue
    private long id;

@ManyToOne
    @JoinTable(name="category_activity",
    joinColumns={@JoinColumn(name="activities_id")},
    inverseJoinColumns={@JoinColumn(name="Category_id")})
    private Category category;
}

和类别类:

@Entity
public class Category {

    @Id
    @GeneratedValue
    private long id;

    @OneToMany
    @Fetch(FetchMode.JOIN)
    @JoinTable(name = "category_activity",
    joinColumns = { @JoinColumn(name = "Category_id") }, 
    inverseJoinColumns = { @JoinColumn(name = "activities_id") })
    @JsonIgnore
    private Collection<Activity> activities;
}

我使用此查询来获取活动:

session.createQuery("from Activity a join a.category cs where cs.id= :categoryId order by a.key").setLong("categoryId", categoryId).list();

JSON 格式的结果不正确,如下所示:

[[{"id":26,"key":"other","name":"Other","cost":100.0,"category":{"id":10,"name":"General","description":""}},{"id":10,"name":"General","description":""}]]

正如你所看到的,类别被打印了两次,并且我们在它周围有一个额外的 []。 当我在类别类中使用另一种一对多关系机制时,例如:

@OneToMany(targetEntity = Activity.class, mappedBy = "category", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JsonIgnore
private Collection<Project> activities;

在活动类中:

@ManyToOne(optional = false)
    private Category category;

这个查询:

session.createQuery("from Activity as a where a.category.id= :categoryId order by a.key").setLong("categoryId", categoryId).list();

一切正常。但我必须使用连接表,因为我不打算更改数据库。

正确的结果应该是这样的:

[{"id":26,"key":"other","name":"Other","cost":100.0,"category":{"id":10,"name":"General","description":""}}]

我很感激任何帮助。


在多方定义联接表,但不要在一侧再次定义它。这将创建与同一表映射的两个单向关联,而不是一个双向关联。

双向关联始终有一个所有者端(您可以在其中指定要使用的联接列或联接表,以及一个反面,它表示它是使用mappedBy属性的另一端的反面:

public class Activity {

    @ManyToOne // owner side: it doesn't have mappedBy, and can decide how the association is mapped: with a join table
    @JoinTable(name="category_activity",
               joinColumns={@JoinColumn(name="activities_id")},
               inverseJoinColumns={@JoinColumn(name="Category_id")})
    private Category category;
}

public class Category {
    @OneToMany(mappedBy = "category") // inverse side: it has a mappedBy attribute, and can't decide how the association is mapped, since the other side already decided it.
    @Fetch(FetchMode.JOIN)
    @JsonIgnore
    private Collection<Activity> activities;
}

EDIT:

此外,您的查询应该通过添加 select 子句仅选择活动,而不是查询连接的所有实体:

select a from Activity as a where a.category.id= :categoryId order by a.key
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Jersey 的 JAX-RS 的休眠资源类中具有连接表的多对一 的相关文章

随机推荐