Spring、JPA、組み込みH2データベースを使用して簡単なアプリケーションを作成しようとしています。最近、宣言型トランザクションでこの奇妙な問題に遭遇しました。@Repositoryアノテーションを使用してDAOを自動配線すると、コミットされません。具体的には、フラッシュで例外が発生します。
javax.persistence.TransactionRequiredException:
Exception Description: No transaction is currently active
これが私の設定です:
persistence.xml
<persistence-unit name="schedulePU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:~/scheduleDB" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="eclipselink.target-database" value="org.eclipse.persistence.platform.database.H2Platform" />
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.logging.level" value="FINE"/>
</properties>
</persistence-unit>
実在物
@Entity
@Table(name = "Professors")
public class Professor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
public Professor() { }
public Professor(String name) {
this.name = name;
}
}
DAO
@Repository
public class JpaDao {
@PersistenceContext
private EntityManager em;
@Transactional
public void addProfessor(Professor professor) {
em.persist(professor);
em.flush();
}
}
database.xml(ルートスプリングコンテキストから含まれる)
<beans>
<context:component-scan base-package="com.spybot.schedule.dao" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="schedulePU" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
コントローラ
@Controller
public class HomeController {
@Inject
JpaDao dao;
@RequestMapping("/add")
public @ResponseBody String add(String name) {
Professor p = new Professor(name);
dao.addProfessor(p);
return ":)";
}
}
そして今、興味深い部分です。DAOから@Repositoryアノテーションを削除し、それをdatabase.xmlで明示的に指定すると、すべてが正常に機能します。
アップデート
別のサーブレット構成<tx:annotation-driven />
を春のサーブレット構成に入れると問題が解決しますが、なぜですか?