Question

I am working on an application in which there are users with regular fields such as userId, name etc., additionally users also have score and rank. rank is calculated on request, depending on the score of the user. it actually is the order of the user in the whole system, the user's rank with highest score is 1.

I am using hibernate 4 for orm and mysql 5.1... for db ; my User class is as follows, as I said earlier rank is not a column in the db;

@Entity
@Table(name = "users")
public class User implements Serializable {


    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(insertable = false, updatable = false)
    Integer userId;


    @Column
    String name;

    @Column
    Integer score;

    Integer rank; // rank is calculated according to score

    ...

here is the sql statement to retrive the order of the user;

SELECT COUNT( score ) + 1 as rank
FROM users 
WHERE users.score > ( SELECT users.score 
                        FROM users WHERE `users`.`userId` = :uid)

I can also use stored db function or procedure.

Is it possible to retrieve user's rank on each request as if it is nested, along with other attributes of the user entity?

Solutions using annotations is much appriciated.

Was it helpful?

Solution

I believe what you want is to investigate the @Formula annotation. It simply drops in whatever snippet you put in there as part of the select clause for that column, and makes that property read-only. (@ColumnTransformer is the same idea except it supports two-way functions.)

Something like the below should work:

@Formula("(SELECT COUNT( score ) + 1 FROM users u WHERE u.score > ( SELECT score FROM users u2 WHERE u2.userId = id))")
Integer rank; 

Note: the id is not qualified, and hibernate will generate the alias prefix for the table of User class.

Not a particularly well-documented feature of Hibernate. But see: http://docs.jboss.org/hibernate/core/4.3/manual/en-US/html/ch05.html#mapping-declaration-property - 5.1.4.1.5. Formula.

You might look at http://www.jroller.com/eyallupu/entry/hibernate_derived_properties_performance_and.

You can make it lazy too in the normal way.

Alternative

You could also make a users view which has this sql embedded in it. This might be valuable in some cases, but will make your entity read-only. (Some databases do support DML against views, but I can't say how well that would work in this case, and you asked for a Hibernate based solution.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top