简体   繁体   中英

hibernate - How to do a Projection based on a subquery using Criteria API?

I'm having a hard time trying to figure this out. The problem is, i have a table containing the score of users in a specific game. So, i have 2 entities called User and Game. Users have no direct relationship to a Game, but ai have a View in the database that has the following field:

public UserScore implements Serializable {
    @Id
    @ManyToOne
    private Game game;
    @Id
    @ManyToOne
    private User user;
    private Long score;
}

So, what ai need is, given a User and a Game, i need the classification of this user in that game based o his score. The SQL query that do this is the following:

select user.name as name,
    scores.score as myScore,
    count(distinct countScores.score) as classification
from user INNER JOIN userscore as scores ON user.id = scores.user_id,
    userscore as countScores
where user.id = 66 and scores.game_id = 666
    and countScores.game_id = 666 and countScores.score > scores.score
group by user.id;

Assuming that 66 is the ID of the user you want the classification position and 666 the ID of the game that you are considering. So, this works, but how to translate it to the Hibernate criteria API? Since i can't create a Criteria with multiple root entities, i tryed to do the following:

DetachedCriteria countCriteria = DetachedCriteria.forClass(UserScore.class, "countScores")
    .add(Restrictions.eq("game.id", 666))
    .add(Restrictions.gtProperty("score", "scores.score"))
    .setProjection(Projections.countDistinct("score"));
this.session.createCriteria(User.class)
    .add(Restrictions.eq("id", 66))
    .createAlias("userScore", "scores", JoinType.INNER_JOIN, Restrictions.eq("game", 666))
    .setProjection(Projections.projectionsList()
        .add(Projections.property("name"), "name")
        .add(Projections.property("scores.score"), "myScore")
        .add(Projections.groupProperty("id"))
        // Here is where this is killing me:
        // .add(Projections.SOMETHING(countCriteria), "classification")
    );
...

So, this is the problem, how i can select as a field in the return set the result of a subquery? There must be a way to do that, otherwise i have no ideas to solve this dilema.

Thank you in advance.

您可以创建另一个DetachedCriteria ,然后按以下方式加入它们:

someNewDetachedCriteria.add(Subqueries.propertyEq("classification", countCriteria));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM