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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With