[解決済み] Spring - 現在のスレッドで利用可能な実際のトランザクションを持つ EntityManager がない - 'persist' 呼び出しを確実に処理することができない。
質問
Spring MVCのWebアプリケーションで、エンティティモデルをデータベースに保存するために"persist"メソッドを呼び出そうとすると、このエラーが表示されます。このエラーに関連する投稿やページをインターネットで見つけることができません。このエラーは、EntityManagerFactoryビーンに問題があるように思えますが、私はSpringプログラミングのかなり初心者なので、私にとっては、すべてがうまく初期化されているように見え、Web上のさまざまなチュートリアル記事に従っているようです。
ディスパッチャサブレット.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/data/repository
http://www.springframework.org/schema/data/repository/spring-repository-1.5.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.2.xsd">
<context:component-scan base-package="wymysl.Controllers" />
<jpa:repositories base-package="wymysl.repositories"/>
<context:component-scan base-package="wymysl.beans" />
<context:component-scan base-package="wymysl.Validators" />
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.orm.hibernate4.HibernateExceptionTranslator"/>
<bean id="passwordValidator" class="wymysl.Validators.PasswordValidator"></bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
<property name="username" value="system" />
<property name="password" value="polskabieda1" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:./META-INF/persistence.xml" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.H2Dialect" />
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
</props>
</property>
</bean>
<mvc:annotation-driven />
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
</bean>
<bean name="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:resources mapping="/resources/*" location="/resources/css/"
cache-period="31556926"/>
</beans>
RegisterController.java
@Controller
public class RegisterController {
@PersistenceContext
EntityManager entityManager;
@Autowired
PasswordValidator passwordValidator;
@InitBinder
private void initBinder(WebDataBinder binder) {
binder.setValidator(passwordValidator);
}
@RequestMapping(value = "/addUser", method = RequestMethod.GET)
public String register(Person person) {
return "register";
}
@RequestMapping(value = "/addUser", method = RequestMethod.POST)
public String register(@ModelAttribute("person") @Valid @Validated Person person, BindingResult result) {
if(result.hasErrors()) {
return "register";
} else {
entityManager.persist(person);
return "index";
}
}
解決方法は?
私も同じ問題があり、メソッドにアノテーションを付けました。
@Transactional
で、うまくいきました。
UPDATE: Springのドキュメントをチェックすると、デフォルトではPersistenceContextはTransaction型なので、このメソッドはトランザクションでなければならないようです( http://docs.spring.io/spring/docs/current/spring-framework-reference/html/orm.html ):
PersistenceContextアノテーションは、オプションの属性タイプを持っています。 で、デフォルトはPersistenceContextType.TRANSACTIONです。このデフォルトは は、共有EntityManagerプロキシを受信するために必要なものです。そのため 代替案であるPersistenceContextType.EXTENDEDは、全く別のものです。 とは別の問題です。この結果、いわゆる拡張EntityManagerになります。 これはスレッドセーフではないので、同時並行的に行われる にアクセスするコンポーネント、例えばSpringで管理されたシングルトンビーンのようなものです。拡張された EntityManagerは、ステートフルなコンポーネントで使用されることを想定しています。 例えば、セッションに存在し、そのライフサイクルでは EntityManagerは、現在のトランザクションに縛られることなく、むしろ アプリケーションに完全に委ねられる。
関連
-
[解決済み] HashMapのtoString関数はなぜ異なる順序で自分自身を印刷するのですか?
-
[解決済み] enumのordinalを使用するのは良い習慣ですか?
-
[解決済み] パラメータ[変数]の不正な修飾子;finalのみが許可される[closed]。
-
[解決済み] java.lang.ClassCastException: java.util.Arrays$ArrayList は java.util.ArrayList にキャストできません。
-
[解決済み] Java Swingで複数のボタンに対して複数のActionListenersを追加する方法
-
[解決済み] java.lang.ClassNotFoundException: クラス com.ibm.db2.jcc.DB2Driver が Worklight プラットフォームまたはプロジェクトに見つかりませんでした。
-
[解決済み] JAVA_OPTIONS、JAVA_TOOL_OPTIONS、JAVA_OPTSの違いについて
-
[解決済み] Mavenです。JARは空になります - 含有するためにマークされたコンテンツがありません
-
[解決済み] java.lang.ClassCastException: java.lang.Long を java.lang.Integer にキャストできない(java 1.6
-
[解決済み] javaでメソッドを呼び出すプログラムのエラー修正
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] java.sql.SQLException: ORA-00933: SQL コマンドが正しく終了していません。
-
[解決済み] getContentPane()は具体的に何をするのですか?
-
[解決済み] なぜJPAには@Transientアノテーションがあるのですか?
-
[解決済み] java.lang.IncompatibleClassChangeError: Mongo クラスを実装しています。
-
[解決済み] java.util.concurrent.ExecutionException 例外をどのように処理しますか?
-
[解決済み] Oracle DB : java.sql.SQLException: 閉じた接続
-
[解決済み] double 型を Int 型に変換、切り捨て
-
[解決済み] Java の条件付きコンパイル:コードチャンクをコンパイルしないようにするには?
-
[解決済み] javax.naming.NameNotFoundException
-
[解決済み] java.util.MissingFormatArgumentException: 形式指定子 '%s' がありません。