I've got two model classes, receipe and rating. The rating class contains rating values like recommendation (yes/no), and a raing value for the receipe. One recipe may contain several ratings from different users.
When a receipe instance is fetched I want it to contain the average rating and the number of recommendations calculated from the ratings.
What is the best way to do this?
Code:
@Entity
@Table(name = "rating")
public class Rating implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "RATINGID")
private Long id;
@Column(name = "RATINGVALUE")
private int ratingValue;
@Column(name = "RECOMMENDATION")
private int recommendation;
@ManyToOne
@JoinColumn( name = "RECIPEID" )
private Recipe recipe;
@ManyToOne
@JoinColumn( name = "USERID" )
private User user;
Code:
@Entity
@Table(name = "recipe")
public class Recipe implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "RECIPEID")
private Long id;
@Column(name = "RECIPETITLE")
private String recipeTitle;
@Column(name = "INGREDIENTS")
private String ingredients;
@Column(name = "DIRECTIONS")
private String directions;
@Transient
private String avgRating;
@Transient
private String numRecommendations;
I have tried to fetch it using the addScalar function, and this works. The only drawback is that the receipe contains categories, and after a receipe is fetched it won't map any categories. So I'm looking for a better solution..
Code:
public static List getRecipes(String title) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
List<Recipe> recipeList = session.createSQLQuery("select r.recipeId as id, r.recipeTitle as recipeTitle, " +
"r.ingredients as ingredients, r.directions, r.userId, " +
"avg(ra.ratingValue) as avgRating, count(ra.recommendation) as numRecommendations " +
"from Recipe r, Rating ra " +
"where r.recipeTitle LIKE :title " +
"and ra.recommendation = 1 " +
"and r.recipeId = ra.recipeId " +
"group by r.recipeId")
.addScalar("id", Hibernate.LONG)
.addScalar("avgRating", Hibernate.STRING)
.addScalar("numRecommendations", Hibernate.STRING)
.addScalar("recipeTitle", Hibernate.STRING)
.addScalar("ingredients", Hibernate.STRING)
.addScalar("directions", Hibernate.STRING)
.setResultTransformer(Transformers.aliasToBean(Recipe.class))
.setString("title", "%"+title+"%")
.list();
return recipeList;
}