PersonとBookの2つのエンティティがあります。特定の本のインスタンスが1つだけシステムに保存されます(本が追加されると、アプリケーションは、データベースに新しい行を追加する前に、その本がすでに見つかっているかどうかを確認します)。エンティティの関連するソースコードは以下にあります:
@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;
}
私の問題は、特定の人が所有する本のいくつかを所有している人を見つけたいということです。返される人のリストは、次のロジックを使用して並べ替える必要があります。同じ本のほとんどを所有している人はリストの最初にあり、リストの2番目の人は最初の人ほど多くの本を所有していません。第三者。このクエリを実行するメソッドのコードを以下に追加します。
@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オブジェクトにマップして戻すことができないようです。