我正在使用Jersey实现RESTful Web服务。我使用hibernate模式与数据库(mySQL)通信。我的hibernate资源类包括:
@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; }
和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":""}]]
如您所见,类别被打印2次,并且在其周围有一个额外的[]。当我在Category类中使用一对多关系的另一种机制时:
@OneToMany(targetEntity = Activity.class, mappedBy = "category", fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JsonIgnore private Collection<Project> activities;
在Activity类中:
@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":""}}]
感谢您的帮助。
在多个方面定义联接表,但不要在一侧再次定义它。这将创建映射到同一表的两个单向关联,而不是一个双向关联。
双向关联始终具有所有者侧(您可以在其中指定要使用的连接列或连接表),以及通过使用mapledBy属性可以说是另一侧的反向的反向侧:
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; }
编辑:
此外,您的查询应仅通过添加select子句来选择活动,而不是查询所连接的所有实体:
select a from Activity as a where a.category.id= :categoryId order by a.key