JPA deleteのトラブルシューティングとトランザクション.
プロジェクトの進行中にJPAコードを作成中に予期せぬエラーが発生しました.
前提条件:Spring Data JPAのRepositoryは、命名規則に従ってクエリーを自動的に生成します.
(参考資料:Spring Data JPA命名規則。)
ユーザと課題の情報を用いて,マルチ対マルチマッピングの関係からEntityを削除しようとした.
ex)deleteByUserAndChallenge->userとchallengeのエンティティ情報を受信することによってクエリーを作成します.
この過程で、私たちは間違いに遭遇しました.私たちがいろいろな方法で知った概念をまとめたいと思います.
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call;
次のエラーが発生し、removeを呼び出すことができません.
問題分析.
まず、現在のドメインは次のとおりです.
saveは正常ですが、findByUserAndChallengeは上記のエラーを投げ出すので、PKをインポートした部分でエラーになる可能性があるので、Domainのプライマリ・キーを変更して実行しました.
プロセスID->(ユーザPK、質問PK)を使用してデフォルトキーを変更します.
deleteBy~の操作では,誤った仮定はPKではなく値によって消去される.
プロセスdeleteBy~をブラウズする動作.
後述するユーザ、質問中のパラメータが無効であるかどうか、deleteByIdおよびdeleteBy~の動作を検索する方法を決定します.
まず、JPA RepositoryのdeleteとdeleteByIdコードを参照してください.
deleteの場合、entitymanagerのremove関数を使用して、永続性コンテキストがクリアされているかどうかを確認できます.
deleteByIdはfindByIdを使用して永続性コンテキストをインポートし、deleteの呼び出しを確認できます.
また、JPAの方法でクエリーを生成するプロセスは、次のとおりです.
Stackoverflowでは良い説明がありました.( リンク )
Proxyアレイを使用し、メソッドインタフェースの機能を使用してPartTreeに従ってメソッドを作成します.すなわち,queryの作成方式はfindBy~とdeleteBy~と変わらないので,一つの方法を試みた.FindByUserAndChallenge検索Entity. delete Entity持続性を削除します. プログラム作成後の結果を確認しました:
コースfindById、delete、deleteByIdの違いを検索します.FindByUserAndChallenge->Delete(T Entity):操作O ByUserAndChallengeの削除:操作X ここで、エラーメッセージを再度確認し、delete内部ライブラリを確認したところ、漏れが見つかりました.
"No EntityManager with actual transaction available for current thread"
後でthreadに関連するエラーを確認しdeleteの関数を確認しました.
@Transactional音声認識.
デフォルトでは、JPAはトランザクションを提供するので、2つ以上のDBでなければトランザクションを適用する必要はないというエラーが発生します.ドメイン変更
トラブルシューティングと考察
データベースにアクセスすると、読み込みはトランザクションにあまり影響しませんが、deleteやinsertのように直接データベースを変更する動作がロックされているか、コミットに基づいてロールバックされているか、トランザクションに敏感であることを再確認できます.
+追加する内容や不足点があれば、メッセージを残してください!:)
前提条件:Spring Data JPAのRepositoryは、命名規則に従ってクエリーを自動的に生成します.
(参考資料:Spring Data JPA命名規則。)
ユーザと課題の情報を用いて,マルチ対マルチマッピングの関係からEntityを削除しようとした.
ex)deleteByUserAndChallenge->userとchallengeのエンティティ情報を受信することによってクエリーを作成します.
この過程で、私たちは間違いに遭遇しました.私たちがいろいろな方法で知った概念をまとめたいと思います.
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call;
次のエラーが発生し、removeを呼び出すことができません.
問題分析.
まず、現在のドメインは次のとおりです.
public class UserChallenge {
@Id
@GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "USER_ID")
private User user;
@ManyToOne
@JoinColumn(name = "CHALLENGE_ID")
private Challenge challenge;
}
ユーザーと質問をマップするには、次のように、新しいドメインで関係をManyToOneにマップしました.saveは正常ですが、findByUserAndChallengeは上記のエラーを投げ出すので、PKをインポートした部分でエラーになる可能性があるので、Domainのプライマリ・キーを変更して実行しました.
プロセスID->(ユーザPK、質問PK)を使用してデフォルトキーを変更します.
@IdClass(UserChallengePK.class)
public class UserChallenge {
@Id
@ManyToOne
@JoinColumn(name = "ID")
private User user;
@Id
@ManyToOne
@JoinColumn(name = "CHALLENGE_ID")
private Challenge challenge;
}
ドメインのプライマリ・キーを次のように変更します.public class UserChallengePK implements Serializable {
private Integer user;
private Long challenge;
}
public interface UserChallengeRepository extends JpaRepository<UserChallenge, UserChallengePK> {
UserChallenge save(UserChallenge userChallenge);
void deleteByUserAndChallenge(User user, Challenge challenge);
}
プライマリ・キーに関する情報を入力して実行しましたが、結果は同じです.deleteBy~の操作では,誤った仮定はPKではなく値によって消去される.
プロセスdeleteBy~をブラウズする動作.
後述するユーザ、質問中のパラメータが無効であるかどうか、deleteByIdおよびdeleteBy~の動作を検索する方法を決定します.
まず、JPA RepositoryのdeleteとdeleteByIdコードを参照してください.
deleteの場合、entitymanagerのremove関数を使用して、永続性コンテキストがクリアされているかどうかを確認できます.
deleteByIdはfindByIdを使用して永続性コンテキストをインポートし、deleteの呼び出しを確認できます.
また、JPAの方法でクエリーを生成するプロセスは、次のとおりです.
Stackoverflowでは良い説明がありました.( リンク )
Proxyアレイを使用し、メソッドインタフェースの機能を使用してPartTreeに従ってメソッドを作成します.すなわち,queryの作成方式はfindBy~とdeleteBy~と変わらないので,一つの方法を試みた.
コースfindById、delete、deleteByIdの違いを検索します.
"No EntityManager with actual transaction available for current thread"
後でthreadに関連するエラーを確認しdeleteの関数を確認しました.
@Transactional音声認識.
デフォルトでは、JPAはトランザクションを提供するので、2つ以上のDBでなければトランザクションを適用する必要はないというエラーが発生します.
@Transactional
public void leaveChallenge(Long id, User user){
Challenge findChallenge = isExistChallenge(id);
userChallengeRepository.deleteByUserAndChallenge(user, findChallenge);
}
トランザクションを上記のサービスの関数に適用すると、エラーが解決されます.トラブルシューティングと考察
データベースにアクセスすると、読み込みはトランザクションにあまり影響しませんが、deleteやinsertのように直接データベースを変更する動作がロックされているか、コミットに基づいてロールバックされているか、トランザクションに敏感であることを再確認できます.
+追加する内容や不足点があれば、メッセージを残してください!:)
Reference
この問題について(JPA deleteのトラブルシューティングとトランザクション.), 我々は、より多くの情報をここで見つけました https://velog.io/@qf9ar8nv/JPA-다대다-deleteBy-문제-해결-및-작동방식-이해テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol