9

私はJerseyを使用してRESTfulWebサービスを実装しています。私はデータベース(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;
}

および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クラスで1対多の関係の別のメカニズムを使用する場合:

@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":""}}]

助けてくれてありがとう。

4

1 に答える 1

19

結合テーブルを多側で定義しますが、片側でもう一度定義しないでください。これにより、1つの双方向アソシエーションではなく、同じテーブルにマップされた2つの単方向アソシエーションが作成されます。

双方向アソシエーションには、常に所有者側(使用する結合列または結合テーブルを指定する側)と、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;
}

編集:

また、クエリでは、select句を追加して、アクティビティのみを選択し、クエリによって結合されたすべてのエンティティを選択する必要はありません。

select a from Activity as a where a.category.id= :categoryId order by a.key
于 2012-07-07T22:24:02.910 に答える