ManyToOneリレーションを持つエンティティのHibernate Projectionsを使用して、SQLクエリで使用する列を減らします
-
06-07-2019 - |
質問
" select * from A"を避けるために、より小さなSQLを作成しようとしています。これは、Hibernate Criteriaのデフォルトでビルドされています。
" Transformers"を介して単純なフィールド(リレーションなし)を使用すると、このSQLを管理できます:
select description, weight from Dog;
こんにちは、私はこのエンティティを持っています:
@Entity
public class Dog
{
Long id;
String description;
Double weight;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "person_id", nullable = false)
Person owner;
}
@Entity
public class Person
{
Long id;
String name;
Double height;
Date birthDate;
}
私の目標はこれを持つことです
select description, weight, owner.name from Dog
基準(および副基準)でこれを試しました:
Criteria dogCriteria = sess.createCriteria(Dog.class);
ProjectionList proList = Projections.projectionList();
proList.add(Projections.property("description"), description);
proList.add(Projections.property("weight"), weigth);
dogCriteria.setProjection(proList);
Criteria personCriteria = dogCriteria.createCriteria("owner");
ProjectionList ownerProList = Projections.projectionList();
ownerProList.add(Projections.property("name"), description);
dogCriteria.setProjection(ownerProList); //After this line, debugger shows that the
//projection on dogCriteria gets overriden
//and the query fails, because "name" is
//not a field of Dog entity.
どのように射影を使用して、より小さなSQL、より少ない列を取得する必要がありますか? 事前に感謝します。
解決
まず、
select description, weight, owner.name from Dog
は有効なSQLではありません。次のようなものでなければなりません
select description, weight, Person.name
from Dog join Person on Dog.person_id = Person.id
代わりに。第二に、なぜですか?必要なことを行うことは可能ですが(以下を参照)、Criteria APIを介して行うことは非常に冗長であり、表示するものは何もありません。数列のデータ転送の節約は、その列が巨大な塊であるか、何十万ものレコードを選択していない限り、無視できます。どちらの場合でも、この問題に対処するより良い方法があります。
誰でも、条件に必要なことを行うには、エイリアスを介してリンクテーブル(個人)に参加し、上記のエイリアスを使用して main 条件で投影を指定する必要があります:
Criteria criteria = session.createCriteria(Dog.class, "dog")
.createAlias("owner", "own")
.setProjection( Projections.projectionList()
.add(Projections.property("dog.description"))
.add(Projections.property("dog.weight"))
.add(Projections.property("own.name"))
);
上記の説明と例は基準予測ドキュメント。上記の基準を実行すると、オブジェクト配列のリストが返されることに注意してください。 ResultTransformer を指定する必要があります。 a>結果を実際のオブジェクトに変換するため。
他のヒント
私はまだ自分で試してはいませんでしたが、Entity(Pojo)で別のコンストラクターを使用して、そこに列を渡すこともできると思います。 https://www.thoughts-on-java.org/hibernate-を参照してください。ベストプラクティス/ の章" 1.2 Pojo"詳細な手順については。 私にとっては、これがManyToOne関係でも機能するかどうかはまだ明確ではありません。試してみます。