データベースに何かを書き込もうとしていますが、「要求が正常に完了しました」と報告されても機能しません。成功した後、すべてが正常に機能しているように見え、コントローラーが正しくリダイレクトされます。
デバッグ
DEBUG a.d.p.payment.PaymentServiceImpl - Requesting to persist new user'max_test@test.com'.
DEBUG a.d.p.payment.model.PaymentDAOImpl - Persisting com.app.payment.model.PaymentUser@86ceb985.
DEBUG o.s.o.j.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler - Creating new EntityManager for shared EntityManager invocation
DEBUG org.hibernate.impl.SessionImpl - opened session at timestamp: 13771737739
DEBUG o.h.e.def.AbstractSaveEventListener - delaying identity-insert due to no transaction in progress
DEBUG o.s.o.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Invoking afterPropertiesSet() on bean with name 'redirectForm'
DEBUG o.s.web.servlet.DispatcherServlet - Rendering view [org.springframework.web.servlet.view.JstlView: name 'redirectForm'; URL [/WEB-INF/jsp/redirectForm.jsp]] in DispatcherServlet with name 'payment'
DEBUG o.s.web.servlet.view.JstlView - Forwarding to resource [/WEB-INF/jsp/redirectForm.jsp] in InternalResourceView 'redirectForm'
DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
appContext.xml (ルート コンテキスト)
<context:annotation-config />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="username" value="test" />
<property name="password" value="test" />
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<!--payment_test is the name of the schema -->
<property name="url" value="jdbc:mysql://test1.com:3306/payment_test" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="payment" />
<property name="persistenceUnitManager">
<bean class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager" >
<property name="defaultDataSource" ref="dataSource" />
</bean>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
</bean>
<context:component-scan base-package="com.app.payment" />
<context:annotation-config />
<!-- Auto scan the components -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" />
<tx:annotation-driven />
支払いユーザー
@Entity
@Table(name="PaymentUser")
public class PaymentUser {
@Id
@GeneratedValue
private int id;
...
}
支払いサービス
@Transactional("transactionManager")
@Service()
public class PaymentServiceImpl implements PaymentService {
@Autowired
private PaymentDAO paymentDAO;
// ... service methods
}
支払いDAO
@Repository()
public class PaymentDAOImpl implements PaymentDAO {
//@PersistenceContext(unitName="payment")
@PersistenceContext()
EntityManager em;
}
トランザクションすら開始していないようです。誰かが私を助けるのに十分な情報であることを願っています. 助けてくれてありがとう。
アップデート
データの取得はうまくいきます。永続化 (EntityManager em.persist()
) と削除 ( em.remove
) が機能していません。正しい問題があるでしょうか。読み取り権のみを意味し、書き込み権はありませんが、この場合、私が考えたエラーがあるはずです。
更新 2
<aop:scoped-proxy />
私の dataSource Bean に追加されましたが、変更はありません。私のデバッグメッセージが言ったように
DEBUG o.h.e.def.AbstractSaveEventListener - delaying identity-insert due to no transaction in progress
トランザクションはありませんが、どこからトランザクションを開始すればよいですか?
Spring: Annotation-driven Transaction Manager の問題も確認しまし たが、どうすればよいかわかりません。
新しい appContext
<?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:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:annotation-config />
<tx:annotation-driven />
<!-- Auto scan the components
<bean id="paymentDao" class="com.app.payment.model.PaymentDAOImpl" />
<bean id="paymentService" class="com.app.payment.PaymentServiceImpl" />
should do the same
-->
<context:component-scan base-package="com.appn.payment" />
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" lazy-init="false" destroy-method="close">
<aop:scoped-proxy />
<property name="username" value="user" />
<property name="password" value="pw" />
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://test1.com:3306/test" />
<!-- <property name="testOnBorrow" value="true" />
<property name="validationQuery" value="SELECT 1" />-->
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="payment" />
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitManager">
<bean class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager" >
<property name="defaultDataSource" ref="dataSource" />
</bean>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<!-- <property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" /> -->
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
<property name="packagesToScan" value="com.app.payment" />
</bean>
<tx:annotation-driven />
</beans>
更新 3
PaymentDAO をフラッシュしようとするem.flush()
と、エラー メッセージが表示されます。
javax.persistence.TransactionRequiredException: no transaction is in progress at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:792)
つまり:
public void flush() {
if ( !isTransactionInProgress() ) {
throw new TransactionRequiredException( "no transaction is in progress" );
}
try {
getSession().flush();
}
catch ( RuntimeException e ) {
throw convert( e );
}
}
特別なセッションが必要ですか?コントローラーにも記録しました
log.info("Is transaction active " + TransactionSynchronizationManager.isActualTransactionActive());
結果はfalseになります...アクティブなトランザクションがない理由がわかりません...
更新 4
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Transactional
@Repository
public class PaymentDAOImpl implements PaymentDAO {
private final Logger log = LoggerFactory.getLogger(getClass());
//@PersistenceContext()
@PersistenceContext(unitName="payment")
EntityManager em;
@Override
public void persist(PaymentUser user) {
log.debug("Persisting {}.", user);
em.persist(user);
//em.flush();
}
@Override
public void remove(PaymentUser user) {
log.debug("Removing {}.", user);
em.remove(user);
}
@Override
public List<PaymentUser> getPaymentUsers() {
log.debug("Fetching payment users.");
return em.createQuery("FROM PaymentUser", PaymentUser.class).getResultList();
}
@Override
public PaymentUser getPaymentUserById(String userId) {
log.debug("Fetching payment users with id '{}'.",userId);
return em.createQuery(
"FROM PaymentUser WHERE userId = :userId", PaymentUser.class)
.setParameter("userId", userId).getSingleResult();
}
@Override
public void removePaymentUserById(String userId) {
log.debug("Removing payment users with id '{}'.",userId);
em.createQuery("DELETE FROM PaymentUser WHERE userId = :userId ", PaymentUser.class).
setParameter("userId", userId).executeUpdate();
}
@Override
public void mergePaymentUser(PaymentUser user) {
log.debug("Merging payment user '{}'.",user);
em.merge(user);
}
}
更新 5
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- springapp servlet -->
<servlet>
<servlet-name>payment</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>payment</servlet-name>
<url-pattern>/payment/*</url-pattern>
<url-pattern>/paymentExternalData</url-pattern>
<url-pattern>/paymentInternalData</url-pattern>
</servlet-mapping>
<!-- Welcome files -->
<welcome-file-list>
<welcome-file>payment.jsp</welcome-file>
<welcome-file>payment.html</welcome-file>
</welcome-file-list>
<!-- S P R I N G -->
<!-- Add Support for Spring -->
<!-- Default applicationContext location: /WEB-INF/applicationContext.xml -->
<!-- UTF-8 filter -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
更新 6
payment-servlet.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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:annotation-config />
<tx:annotation-driven />
<!-- Auto scan the components -->
<context:component-scan base-package="com.app.payment" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
appContext.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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:annotation-config />
<tx:annotation-driven />
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" lazy-init="false" destroy-method="close">
<aop:scoped-proxy />
<property name="username" value="test" />
<property name="password" value="test" />
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://test1.com/test" />
<property name="testOnBorrow" value="true" />
<property name="validationQuery" value="SELECT 1" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="payment" />
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitManager">
<bean class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager" >
<property name="defaultDataSource" ref="dataSource" />
</bean>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
</bean>
</beans>