Spring应用程序似乎不是持久化数据

我正在尝试将一些内容写入我的数据库,但尽管它报告了“成功完成请求”,但它仍无法正常工作。 成功之后,一切似乎都运行良好,我的控制器正确地重定向我。

调试

DEBUG adppayment.PaymentServiceImpl - Requesting to persist new user'max_test@test.com'. DEBUG adppayment.model.PaymentDAOImpl - Persisting com.app.payment.model.PaymentUser@86ceb985. DEBUG osojSharedEntityManagerCreator$SharedEntityManagerInvocationHandler - Creating new EntityManager for shared EntityManager invocation DEBUG org.hibernate.impl.SessionImpl - opened session at timestamp: 13771737739 DEBUG ohedef.AbstractSaveEventListener - delaying identity-insert due to no transaction in progress DEBUG osojpa.EntityManagerFactoryUtils - Closing JPA EntityManager DEBUG osbfsDefaultListableBeanFactory - Invoking afterPropertiesSet() on bean with name 'redirectForm' DEBUG osweb.servlet.DispatcherServlet - Rendering view [org.springframework.web.servlet.view.JstlView: name 'redirectForm'; URL [/WEB-INF/jsp/redirectForm.jsp]] in DispatcherServlet with name 'payment' DEBUG osweb.servlet.view.JstlView - Forwarding to resource [/WEB-INF/jsp/redirectForm.jsp] in InternalResourceView 'redirectForm' DEBUG osweb.servlet.DispatcherServlet - Successfully completed request 

appContext.xml(根上下文)

                             

PaymentUser

 @Entity @Table(name="PaymentUser") public class PaymentUser { @Id @GeneratedValue private int id; ... } 

PaymentService

 @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; } 

似乎它甚至没有开始交易。 希望有足够的信息让某人帮助我。 谢谢你的帮助。

UPDATE

获取数据工作正常。 持久化(EntityManager em.persist() )和删除( em.remove )不起作用。 可能有正确的问题。 意思是只读权限而没有写权限,但在这种情况下我应该有一个错误。

更新2

到我的dataSource bean,但没有更改。 就像我的调试消息说的那样

 DEBUG ohedef.AbstractSaveEventListener - delaying identity-insert due to no transaction in progress 

没有交易,但我的交易应该从哪里开始?

我还检查了问题Spring:Annotation-driven Transaction Manager但我不知道该怎么做。

新的appContext

     <!-- Auto scan the components   should do the same -->         <!--  -->                 <!--  -->        

更新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()); 

结果是错误的…不确定为什么没有活动交易……

更新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 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

    org.springframework.web.context.ContextLoaderListener    payment org.springframework.web.servlet.DispatcherServlet 1   payment /payment/* /paymentExternalData /paymentInternalData    payment.jsp payment.html       characterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter  encoding UTF-8   forceEncoding true    characterEncodingFilter /*   

更新6

支付-servlet.xml中

            

appContext.xml

                                  

确保在两个xml配置中没有完全重复的元素。 如果你有这个,你基本上复制了所有的bean实例。 你最初拥有的是所有bean都被ContextLoaderListener加载,并且由于的存在而被代理。

现在,如果您的payment-servlet.xml中有相同的 ,那么将再次扫描所有创建另一个实例的bean,但是由于没有它不会被代理,也不会应用任何事务。

现在发生的是,只要您需要一个@Service注释bean, DispatcherServlet首先在其自己的ApplicationContext中查看是否有bean来满足其需求。 如果它将被使用(您当前的情况),如果没有它将查询父上下文(由ContextLoaderListener加载的那个)。

您需要做的是配置ContextLoaderListener以扫描所有内容但是 @Controller注释bean和DispatcherServlet 扫描@Controller注释bean。 这可以通过正确配置

applicationContext.xml中

    

支付-servlet.xml中

    

这将为您提供事务,并且只为您的bean提供单个实例。 您应该从payment-servlet.xml文件中删除

仍然存在一个公开的JIRA问题 ,将其包含在参考指南中。 也是Spring社区论坛中的一个主题解释了这一点。

再次查看您的applicationContext.xml,我注意到您没有使用您的transactionManager声明分配entityManager。 我不确定Spring是否会隐式设置它,但如果它不能解释为什么你的坚持不起作用。

例如,更改:

  to    

UPDATE

我只使用容器管理的实体配置了Spring + JPA(看起来也是你的意图) – 从来没有真正的应用程序管理。 据我所知,在使用Spring进行Container管理时,您并不需要配置持久单元。 我不是100%确定这是否有帮助,但尝试更改在applicationContext.xml中声明entityManagerFactory的方式。

         org.hibernate.dialect.MySQL5Dialect true ... //additional props    

使用注释驱动的事务时,应该在使用数据库的方法之前放置@Transactional注释。 它可以是您的DAO或服务方法。 我可以看到你已经将@Transactional置于PaymentServiceImpl之上,但这不是该注释的正确位置。

看来你在DAO实现类的开头就错过了@Transactional注释。 它可以解释为什么你没有打开任何交易。

如果它不足以解决您的问题,您能否给我们完整的DAO实施课程?

设法找到问题。 Spring Docu “@EnableTransactionManagement只在同一应用程序上下文中查找bean上的@Transactional。” 在我的payment-servlet.xml中我没有这就是没有活动事务的原因。

在创建transactionManager bean之后,你应该在Xml文件中启用事务,

要么

如果你写了第二个,那么你必须在你的DAO类中使用@Transaction(),

如果任何方法在写入之前需要事务

@Transactional(propagation = Propagation.REQUIRED,readOnly = false)

它告诉事务是require,readOnly = false意味着你可以读写数据。