私はgetOne()
が遅延ロードされ、findOne()
がエンティティ全体をすぐにフェッチすることを読みました。デバッグログを確認し、SQLサーバーで監視を有効にして、どのステートメントが実行されるかを確認しました。getOne()
とfindOne()
の両方が同じクエリを生成して実行していることがわかりました。ただし、getOne()
を使用すると、値は最初はnullになります(もちろん、idは除きます)。
では、どちらの方法でもデータベースで同じクエリを実行するのであれば、なぜ一方を他方に使用する必要があるのでしょうか。私は基本的に、すべての子/属性を取得せずにエンティティをフェッチする方法を探しています。
EDIT1:
ダオコード:
_@Repository
public interface FlightDao extends JpaRepository<Flight, Long> {
}
_
EDIT2:
Chlebikのおかげで、問題を特定することができました。 Chlebikが述べたように、getOne()
によってフェッチされたエンティティのプロパティにアクセスしようとすると、完全なクエリが実行されます。私の場合、デバッグ中に動作を確認していましたが、一度に1行ずつ移動していましたが、デバッグ中にIDEがデバッグ目的でオブジェクトのプロパティにアクセスしようとしたことを忘れていました(または少なくともそれが私は起こっていると思います)、デバッグは完全なクエリの実行をトリガーします。デバッグを停止してログを確認したところ、すべてが正常に見えます。
getOne()
vs findOne()
(このログはMySQL _general_log
_から取得され、休止状態ではありません。
単なる推測ですが、「純粋なJPA」には、getReferenceというEntityManagerのメソッドがあります。また、IDのみが含まれるエンティティを取得するように設計されています。その使用は主に、エンティティ全体を取得する必要なしに参照が存在することを示すためでした。多分コードはもっと教えてくれるでしょう:
// em is EntityManager
Department dept = em.getReference(Department.class, 30); // Gets only entity with ID property, rest is null
Employee emp = new Employee();
emp.setId(53);
emp.setName("Peter");
emp.setDepartment(dept);
dept.getEmployees().add(emp);
em.persist(emp);
getOneが同じ目的を果たしていると思います。生成されたクエリがあなたが尋ねたものと同じであるのはなぜですか?まあ、JPA聖書のAFAIR-Pro JPA2 by Mike KeithとMerrick Schincariol-ほとんどすべての段落に「動作はベンダーに依存している」のようなものが含まれています。
編集:
自分で設定しました。最後に、あなたが何らかの方法でgetOneでフェッチされたエンティティに干渉すると(entity.getId()でも)、SQLが実行されました。プロキシを作成するためだけに使用している場合(たとえば、上記のコードに示すような関係インジケーターの場合)、何も起こらず、追加のSQLは実行されません。だから私はあなたのサービスクラスであなたがこのエンティティで何かをする(ゲッターを使って何かをログに記録する)と仮定します、そしてそれがこれら二つのメソッドの出力が同じに見える理由です。
IDでEntity
を削除するとします。 SQL
では、次のようなクエリを実行できます。
"delete form TABLE_NAME where id = ?".
そしてHibernate
では、最初にEntity
のマネージドインスタンスを取得し、それをEntityManager.remove
メソッドに渡す必要があります。
Entity a = em.find(Entity.class, id);
em.remove(a);
しかし、この方法では、削除する前に、データベースから削除するEntity
をフェッチする必要があります。それは本当に必要ですか?
メソッドEntityManager.getReference
は、データベースをクエリしてエンティティのプロパティを設定せずにHibernate
プロキシを返します。返されたプロキシのプロパティを自分で取得しようとしない限り。
メソッドJpaRepository.getOne
は、EntityManager.getReference
メソッドの代わりにEntityManager.find
メソッドを使用します。したがって、マネージオブジェクトが必要であるが実際にデータベースにクエリを実行する必要がない場合は、JpaRepostory.getOne
メソッドを使用して不要なクエリを削除することをお勧めします。
データベースに存在するIDでエンティティをクエリすると、findOne(id)
を使用するとnullが取得され、getOne(id)
を使用するとオブジェクトがnullフィールドに取得されるため、getOne(id) == null
は期待どおりに機能しません。
特定のIDのテーブルにデータが見つからない場合、findOneはnullを返しますが、getOneはjavax.persistence.EntityNotFoundExceptionをスローします。どちらにも独自の長所と短所があります。以下の例をご覧ください。
結果がわかっている場合は、要件に応じて更新できます。