使用 Jersey 的 JAX-RS 的休眠资源类中的多对一连接表 [英] Many-To-One with join Table in hibernate resource classes for a JAX-RS using Jersey

查看:14
本文介绍了使用 Jersey 的 JAX-RS 的休眠资源类中的多对一连接表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

I am implementing a RESTful Web Service using Jersey. I use hibernate to communicate with the database (mySQL). My hibernate resource classes includes:

@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;
}

and the Category class:

@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;
}

I used this query to fetch the ativities:

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

The result in JSON format is not right like:

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

As you see category is printed 2 times and we have a extra [] around it. When I use another mechanism of One-To-Many relation in Category class like:

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

And in Activity class:

@ManyToOne(optional = false)
    private Category category;

And this query:

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

Everything works fine. But I have to use join table because I do not suppose to change the database.

The proper result should look like:

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

I appreciate for any help.

解决方案

Define the join table on the many side, but don't define it once again on the one side. This creates two unidirectional associations mapped with the same table instead of one bidirectional association.

A bidirectional association always has an owner side (where you specify the join column or join table to use, and an inverse side which says hat it's the inverse of the other side by using the mappedBy attribute:

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:

Also, your query should only select the activity, and not all the entities joined by the query, by adding a select clause:

select a from Activity as a where a.category.id= :categoryId order by a.key

这篇关于使用 Jersey 的 JAX-RS 的休眠资源类中的多对一连接表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆