SpringとJava EEにおける@PersistenceContextのEntityManagerはスレッドセーフ
SpringやJava EEにおいて、@PersistenceContextアノテーションは、EntityManagerをSpringやJava EEコンポーネントに注入するために使用されます。
Springでは@PersistenceContextアノテーションは@PersistenceUnitアノテーションなどと併用することで EntityManagerFactoryをSpringコンポーネントに注入できる一方、Java EEでは@PersistenceContextアノテーションはEntityManagerを注入することのみできる。
JPA仕様に基づくと、EntityManagerはスレッドセーフではないため、複数のスレッド間で単一のEntityManagerインスタンスを共有することはできません。
スプリングでは、各スレッド毎に独立したEntityManagerインスタンスを持つようにするには@Scope(“prototype”)アノテーションを使用します。これにより、各スレッド毎に独立したパーシスタンスコンテキストを持つため、スレッドセーフティの問題を回避できます。コードサンプルは以下の通りです。
@PersistenceContext
@Scope("prototype")
private EntityManager entityManager;
Java EEでは、デフォルトでは各リクエストはEntityManagerインスタンスを個別に持ちます。これは、Java EEコンテナがリクエストごとにスレッドを作成し、そのスレッド上でEntityManagerインスタンスを作成するためです。つまり、Java EEでは、EntityManagerのスレッドセーフ性はコンテナによって自動的に管理されています。
いずれにしても、Spring/Java EEのどちらにおいても、個々のスレッドごとにEntityManagerインスタンスを持たせることでスレッドセーフを担保することができる。Springでは@Scope(“prototype”)を使うことで、Java EEではコンテナによりデフォルトで管理される。