【问题标题】:Ordering the results of a Hibernate Criteria query by using information of the child entities of the asked entities使用被询问实体的子实体的信息对 Hibernate Criteria 查询的结果进行排序
【发布时间】:2011-02-06 13:07:29
【问题描述】:

我有两个实体 Person 和 Book。只有一个特定书籍的实例存储到系统中(添加书籍时,应用程序会在向数据库添加新行之前检查是否已经找到该书籍)。实体的相关源代码如下:

@Entity
@Table(name="persons")
@SequenceGenerator(name="id_sequence", sequenceName="hibernate_sequence")
public class Person extends BaseModel
{
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "id_sequence")
    private Long id = null;

    @ManyToMany(targetEntity=Book.class)
    @JoinTable(name="persons_books", joinColumns = @JoinColumn( name="person_id"), inverseJoinColumns = @JoinColumn( name="book_id"))
    private List<Book> ownedBooks = new ArrayList<Book>();
}

@Entity
@Table(name="books")
@SequenceGenerator(name="id_sequence", sequenceName="hibernate_sequence")
public class Book extends BaseModel
{
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "id_sequence")
    private Long id = null;

    @Column(name="name")
    private String name = null;
}

我的问题是我想找到拥有特定人拥有的某些书籍的人。返回的人员列表应该使用以下逻辑进行排序:拥有最多相同书籍的人应该在列表的第一位,列表的第二人没有第一人拥有的书籍数量,但超过第三人称。执行该查询的方法代码添加如下:

@Override
public List<Person> searchPersonsWithSimilarBooks(Long[] bookIds) {
    Criteria similarPersonCriteria = this.getSession().createCriteria(Person.class);
    similarPersonCriteria.add(Restrictions.in("ownedBooks.id", bookIds));

    //How to set the ordering?
    similarPersonCriteria.addOrder(null);

    return similarPersonCriteria.list();
}

我的问题是,这可以通过使用 Hibernate 来完成吗?如果是这样,怎么做?我知道我可以实现一个比较器,但我更喜欢使用 Hibernate 来解决这个问题。

当使用 SQL 时,我想要的结果可以通过使用以下 SQL 查询来实现:

select p.name, count(p.name) as bookCount from persons p, books b, person_book pb
where pb.person_id = p.id and pb.book_id = b.id and b.id in (1,2,3,4,5,6) group by
name order by bookCount desc 

我一直在试图弄清楚如何将其转换为 Criteria 查询。我一直在尝试使用 Projections,但我似乎无法将结果映射回 Person 对象。

【问题讨论】:

    标签: java hibernate criteria-api


    【解决方案1】:
    【解决方案2】:

    我终于设法解决了这个问题。以下方法按预期工作:

    @Override
    public List<Person> searchPersonsWithSimilarBooks(Long[] bookIds) {
        Criteria similarPersonCriteria = this.getSession().createCriteria(Person.class, "p");
    
        Criteria bookCriteria = similarPersonCriteria.createCriteria("ownedBooks", "b");
        bookCriteria.add(Restrictions.in("b.id", bookIds));
    
        similarPersonCriteria.setProjection(Projections.projectionList()
                .add(Projections.groupProperty("p.id"), "id")
                .add(Projections.rowCount(), "similarBookCount"));
    
        similarPersonCriteria.addOrder(Order.desc("similarBookCount"));
        similarPersonCriteria.setResultTransformer(new AliasToBeanResultTransformer(Person.class));
    
        return similarPersonCriteria.list();
    }
    

    我还通过添加一个名为 similarBookCount 的瞬态属性更新了我的 person 类,这在某些情况下很有用。

    【讨论】:

      猜你喜欢
      • 2021-02-09
      • 2017-07-27
      • 1970-01-01
      • 1970-01-01
      • 2017-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多