TransactionRequiredException:@Transactional方法中没有可用的事务性EntityManager

时间:2015-10-31 15:11:29

标签: java spring jpa persistence

设计了包含@Transactional方法的Service方法后,我遇到了#34;没有事务性EntityManager可用的问题"。 Technogoly使用:JPA,Spring,Maven

异常stackTrace

Exception in thread "main" javax.persistence.TransactionRequiredException: No transactional EntityManager available
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:273)
at com.sun.proxy.$Proxy29.merge(Unknown Source)
at com.restaurant.DAO.OrderDAOImpl.saveOrder(OrderDAOImpl.java:24)
at com.restaurant.services.DeliveryStaffServiceImpl.changeStatusOfOrder(DeliveryStaffServiceImpl.java:37)
at com.restaurant.entities.Main.main(Main.java:161)

我在main中调用服务的方式:

DeliveryStaffService del = context.getBean(DeliveryStaffService.class);
    List<Order> listOfOrders = del.getListOfOrders();

试图弄清楚尝试的问题:

  1. 检查pom.xml中的Spring版本;
  2. 检查所有@transactional方法是否公开;
  3. 在beans.xml中添加
  4. <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
    

    此外,在同一个项目中有一些@transactional方法的服务,这些服务没有任何问题。

    这是我的persistence.xml:

    <?xml version="1.0" encoding="UTF-8" ?>
    <persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    xmlns="http://java.sun.com/xml/ns/persistence"  version="2.0" >
        <persistence-unit name="Restaurant" transaction-type="RESOURCE_LOCAL">
            <provider>
                 org.eclipse.persistence.jpa.PersistenceProvider
            </provider>
        <properties>
                <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
                <property name="javax.persistence.jdbc.url" value="jdbc:derby:..//RestaurantDB1;create=true" />
                <property name="eclipselink.ddl-generation.output-mode" value="database" />
                     <property name="eclipselink.weaving" value="static" />
        </properties>
        </persistence-unit>
     </persistence> 
    

    的beans.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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd">
    
        <context:component-scan base-package="com.restaurant"/>
    
        <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="packagesToScan" value="com.restaurant"/>
            <property name="dataSource" ref="dataSource"/>
            <property name="persistenceUnitName" value="Restaurant"/>
    
            <property name="jpaDialect"> 
            <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect"/> 
            </property> 
    
            <property name="jpaVendorAdapter"> 
                <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
                    <property value="true" name="showSql"/> 
                    <property value="true" name="generateDdl"/>
                    <property name="databasePlatform" value="org.eclipse.persistence.platform.database.DerbyPlatform"/> 
                </bean> 
            </property>
    
            <property name="jpaPropertyMap">
                <map>
                  <entry key="eclipselink.weaving" value="false" />
                </map>
            </property>
        </bean>
    
        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
              <property name="entityManagerFactory" ref="entityManagerFactory"/> 
        </bean>
    
        <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
    
        <bean id="dataSource"  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
            <property name="url" value="jdbc:derby:..//RestaurantDB1;create=true" /> 
        </bean>
    
        <tx:annotation-driven transaction-manager="transactionManager"/> 
        <tx:annotation-driven proxy-target-class="true"/> 
    </beans>
    

    服务实施

     @Named
    public class KitchenStaffServiceImpl implements KitchenStaffService {
    
        @Inject
        private ItemDAO itemDAO;
        @Inject
        private OrderDAO orderDAO;
    
        @Override
        public List<Item> viewItems() {
            return itemDAO.viewItems();
        }
    
        @Override
        @Transactional
        public void processItem(Item item) {
            int i=item.getQuantity();
            while(i>0){
                try {
                    Thread.sleep(1000);
                    --i;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            item.setIsCooked(true);
            itemDAO.saveItem(item);
            System.out.println(item.getId());
    
            List<Item> list = item.getOrder().getListOfDishes();
            if(list.stream().allMatch(t -> t.getIsCooked()==true)){
                Order ord = item.getOrder();
                ord.setStatus(StatusOfDelivery.READY_FOR_SHIPMENT);
                orderDAO.saveOrder(ord);
            }
        }
    }
    

    DAO实施

        @Repository
    public class ItemDAOImpl implements ItemDAO{
    
        @PersistenceContext
        private EntityManager em; 
    
        @Override
        public void saveItem(Item item){
            if(item.getId()==0){
                em.persist(item);
            }else
                em.merge(item);
        }       
    }
    

    OrderDAOImpelementation with saveOrder(Order order)与ItemDAO相同(persist()/ merge())

    提前感谢任何提议

1 个答案:

答案 0 :(得分:0)

你正在打电话

OrderDAOImpl.saveOrder();

来自方法

DeliveryStaffServiceImpl.changeStatusOfOrder();

但是在示例中,您显示@Transactional注释放在不相关的方法KitchenStaffServiceImpl.processItem()上。最有可能的是,您需要@Transactional上的DeliveryStaffServicleImpl注释。