• Spring—SSJ集成&声明式事务管理


    1.   课程介绍

    • 1.  SSJ集成;(掌握)
    • 2.  声明式事务管理;(掌握)
    1. 什么是三大框架

    2.1.  ssh

    Struts/Struts2 Spring Hibernate

    2.2.  ssm

    SpringMVC Spring MyBatis

    2.3.  ssj

    Struts2 Spring JPA

    SpringMVC Spring JPA

    SpringMVC Spring Data JPA

    1. Spring集成JPA;(掌握)

    Spring4 + Struts2 + jpa/hibernate4

    建议:先完成Spring与jpa的集成

    3.1.  创建动态web工程:

    注意修改classpath路径,创建web文件取名为webapp

    3.2.  拷贝Spring共16的jar文件

    11个spring的jar文件

    spring-framework-3.2.0.RELEASE-dependencies搜索dbcp,pool,aop,wea,logging

     

    3.3.  拷贝JPA共11的jar文件

    hibernate-release-4.3.8.Finallibjpa*.jar

    hibernate-release-4.3.8.Finallib equired*.jar

     

    3.4.  拷贝数据库驱动1个jar文件

    Spring+jpa+驱动共28个jar文件

    3.5.  写一个domain对象,配置JPA映射

    @Entity

    @Table(name = "t_product")

    public class Product {

             @Id

             @GeneratedValue

             private Long id;

             private String name;

    3.6.  Spring的配置文件

    3.6.1.   Bean对象注入的顺序

    jdbc.properties->dataSource->entityManagerFactory->dao->service->junit->action

    3.6.2.   加载jdbc.properties

    jdbc.driverClassName=com.mysql.jdbc.Driver

    jdbc.url=jdbc:mysql:///ssj

    jdbc.username=root

    jdbc.password=root

     

    <?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"

             xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context.xsd">

     

             <!-- 加载jdbc.properties -->

             <context:property-placeholder location="jdbc.properties" />

    3.6.3.   配置连接池dataSource

    <!-- 配置连接池dataSource -->

    <!-- destroy-method="close当前bean销毁的时候,会先调用close方法,关闭连接" -->

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

             <!-- 依赖注入连接池需要的属性 -->

             <!-- property name="是BasicDataSource的set方法,本质属性" -->

             <!-- property value="是jdbc.properties配置文件的key" -->

             <property name="driverClassName" value="${jdbc.driverClassName}" />

             <property name="url" value="${jdbc.url}" />

             <property name="username" value="${jdbc.username}" />

             <property name="password" value="${jdbc.password}" />

    </bean>

    3.7.  配置entityManagerFactory

    3.7.1.   Spring-Reference_2.5_zh_CN.chm

     

    12.6.1.3. LocalContainerEntityManagerFactoryBean

     

    3.7.2.   配置信息

    <!-- org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter引入默认entityManagerFactory名称 -->

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

             <!-- 1.注入DataSource -->

             <property name="dataSource" ref="dataSource" />

             <!-- 2.从哪个包去扫描@Entity,domain包 -->

             <!-- public void setPackagesToScan(String... packagesToScan) { -->

             <property name="packagesToScan" value="cn.itsource.ssj.domain" />

             <!-- 3.配置JPA的实现 -->

             <!-- private JpaVendorAdapter jpaVendorAdapter; -->

             <property name="jpaVendorAdapter">

                      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">

                               <!-- org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter -->

                               <!-- private boolean showSql = false;是否显示sql语句 -->

                               <property name="showSql" value="true" />

                               <!-- private boolean generateDdl = false;是否建表 -->

                               <property name="generateDdl" value="true" />

                               <!-- private String databasePlatform;原来方言 -->

                               <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />

                      </bean>

             </property>

    </bean>

    3.8.  IProductDao

    public interface IProductDao {

             void save(Product product);

     

             void update(Product product);

     

             void delete(Long id);

     

             Product get(Long id);

     

             List<Product> getAll();

    }

    3.9.  ProductDaoImpl

    @Repository

    public class ProductDaoImpl implements IProductDao {

     

             // @Autowired 不能使用这个注入

             @PersistenceContext // 持久层上下文管理器

             private EntityManager entityManager;

     

             @Override

             public void save(Product product) {

                      entityManager.persist(product);

             }

     

             @Override

             public void update(Product product) {

                      entityManager.merge(product);

             }

     

             @Override

             public void delete(Long id) {

                      Product product = get(id);

                      if (product != null) {

                               entityManager.remove(product);

                      }

             }

     

             @Override

             public Product get(Long id) {

                      return entityManager.find(Product.class, id);

             }

     

             @Override

             public List<Product> getAll() {

                      String jpql = "select o from Product o";

                      return entityManager.createQuery(jpql).getResultList();

             }

     

    }

    3.10.         组件扫描

    <!-- 扫描dao、service、action组件 -->

    <!-- 可以处理@Repository, @Service, and @Controller,@Autowired,@PersistenceContext 注解-->

    <context:component-scan base-package="cn.itsource.ssj" />

    3.11.         IProductService

    public interface IProductService {

             void save(Product product);

     

             void update(Product product);

     

             void delete(Long id);

     

             Product get(Long id);

     

             List<Product> getAll();

    }

    3.12.         ProductServiceImpl

    @Service

    public class ProductServiceImpl implements IProductService {

             @Autowired

             private IProductDao productDao;

     

             @Override

             public void save(Product product) {

                      productDao.save(product);

             }

     

             @Override

             public void update(Product product) {

                      productDao.update(product);

             }

     

             @Override

             public void delete(Long id) {

                      productDao.delete(id);

             }

     

             @Override

             public Product get(Long id) {

                      return productDao.get(id);

             }

     

             @Override

             public List<Product> getAll() {

                      return productDao.getAll();

             }

     

    }

    3.13.         声明式事务管理(注解版本)

    在spring的配置文件添加一点事务配置,并且在service层类上面添加一些注解,就可以实现事务管理

    3.13.1.        添加一个tx命名空间

    <?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.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context.xsd

    http://www.springframework.org/schema/tx

    http://www.springframework.org/schema/tx/spring-tx.xsd">

    3.13.2.        添加事务配置

    <!-- 配置事务管理器 -->

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">

             <property name="entityManagerFactory" ref="entityManagerFactory" />

    </bean>

    <!-- 开启注解事务管理 ,解析@Transactional事务注解 -->

    <!-- transaction-manager="transactionManager"默认找bean.id=transactionManager事务管理器 -->

    <tx:annotation-driven />

    3.13.3.        ProductServiceImpl

    @Service

    // 默认事务配置

    // @Transactional

    // 上面配置等价于下面配置

    @Transactional(propagation = Propagation.REQUIRED)

    public class ProductServiceImpl implements IProductService {

             @Autowired

             private IProductDao productDao;

     

             @Override

             public void save(Product product) {

                      productDao.save(product);

             }

     

             @Override

             public void update(Product product) {

                      productDao.update(product);

             }

     

             @Override

             public void delete(Long id) {

                      productDao.delete(id);

             }

     

             @Override

             @Transactional(readOnly=true,propagation=Propagation.SUPPORTS)

             public Product get(Long id) {

                      return productDao.get(id);

             }

     

             @Override

             @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)

             public List<Product> getAll() {

                      return productDao.getAll();

             }

     

    }

    3.14.         Junit

    @Autowired

    IProductService productService;

     

    @Test

    public void save() throws Exception {

             System.out.println("代理类:" + productService.getClass());

             Product product = new Product();

             product.setName("苹果的弟弟");

             productService.save(product);

    }

    代理类:class com.sun.proxy.$Proxy23

    1. Spring集成Struts2

    4.1.  添加struts2的12个jar文件

    没有导入javassist-3.11.0.GA.jar

     

    4.2.  配置web.xml

    <!-- 添加struts核心过滤器 -->

    <filter>

             <filter-name>struts2</filter-name>

             <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

    </filter>

     

    <filter-mapping>

             <filter-name>struts2</filter-name>

             <url-pattern>/*</url-pattern>

    </filter-mapping>

    4.3.  配置struts.xml

    <package name="default" namespace="/" extends="struts-default">

     

             <!-- action代表一个控制器, name="对应的访问的url地址" method="返回action的方法" -->

             <!-- spring集成struts之后,class可以写全限定类名,也可以写bean.id -->

             <!-- product 没有写_的时候,默认就是访问当前action的execute -->

             <!-- product_*写了_input,访问input方法 ,对应后面method={1} -->

     

             <action name="product_*" class="cn.itsource.ssj.action.ProductAction" method="{1}">

                      <!-- 显示列表页面 -->

                      <result>/WEB-INF/views/product.jsp</result>

                      <!-- 显示添加获取修改页面 -->

                      <result name="input">/WEB-INF/views/product_input.jsp</result>

                      <!-- 保存或者删除之后进行重定向 -->

                      <result name="reload" type="redirectAction">product</result>

             </action>

     

    </package>

    4.4.  ProductAction

    public class ProductAction extends ActionSupport {

     

             @Autowired

             IProductService productService;

     

             @Override

             public String execute() throws Exception {

                      ActionContext.getContext().put("products", productService.getAll());

                      return SUCCESS;

             }

    }

    4.5.  配置好,启动tomcat,抛出一下异常

    4.5.1.   具体异常信息

    严重: Exception starting filter struts2

    Class: com.opensymphony.xwork2.spring.SpringObjectFactory

    File: SpringObjectFactory.java

    Method: getClassInstance

    Line: 245 - com/opensymphony/xwork2/spring/SpringObjectFactory.java:245:-1

             at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:493)

             at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:74)

             at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(StrutsPrepareAndExecuteFilter.java:57)

             at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279)

             at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:260)

             at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105)

             at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4700)

             at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5340)

             at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)

             at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)

             at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)

             at java.util.concurrent.FutureTask.run(FutureTask.java:266)

             at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

             at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

             at java.lang.Thread.run(Thread.java:745)

    Caused by: java.lang.NullPointerException

             at com.opensymphony.xwork2.spring.SpringObjectFactory.getClassInstance(SpringObjectFactory.java:245)

             at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.verifyResultType(XmlConfigurationProvider.java:608)

             at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addResultTypes(XmlConfigurationProvider.java:578)

             at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addPackage(XmlConfigurationProvider.java:534)

             at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadPackages(XmlConfigurationProvider.java:295)

             at org.apache.struts2.config.StrutsXmlConfigurationProvider.loadPackages(StrutsXmlConfigurationProvider.java:112)

             at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:264)

             at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:67)

             at org.apache.struts2.dispatcher.Dispatcher.getContainer(Dispatcher.java:967)

             at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:435)

             at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:479)

             ... 14 more

    4.5.2.   为什么会出现异常?

    因为原来struts2的对象都是由xwork的对象处理,现在添加struts2-spring-plugin-2.3.20.jar文件,之后由spring接管了对原来struts2对象的创建

    原因是在struts2-spring-plugin-2.3.20.jar文件里面有这个配置struts-plugin.xml

    <struts>

        <bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />

       

        <!--  Make the Spring object factory the automatic default -->

        <constant name="struts.objectFactory" value="spring" />

     

        <constant name="struts.class.reloading.watchList" value="" />

        <constant name="struts.class.reloading.acceptClasses" value="" />

        <constant name="struts.class.reloading.reloadConfig" value="false" />

     

        <package name="spring-default">

            <interceptors>

                <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>

            </interceptors>

        </package>   

    </struts>

    而spring容器并没有被启动

    4.5.3.   在web.xml添加一个监听器,来实例化spring容器

    <!-- 添加一个监听器,来实例化spring容器 -->

    <listener>

             <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

    </listener>

    4.5.4.   再次启动tomcat,又抛出异常

    Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]

             at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:141)

             at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:330)

             ... 21 more

    默认会去WEB-INF下面找配置文件,而此路径没有

    4.5.5.   在web.xml添加一个上下文的初始化参数,来告诉spring从哪里加载配置文件

    <!-- 添加一个上下文的初始化参数 -->

    <context-param>

             <param-name>contextConfigLocation</param-name>

             <param-value>classpath:applicationContext.xml</param-value>

    </context-param>

    4.5.6.   怎样快速找contextConfigLocation名字

    找监听器ContextLoaderListener的父类ContextLoader

    有一个常量配置

    public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";

    4.5.7.   不能加载jdbc.properties异常

    Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/jdbc.properties]

    4.5.8.   修改spring的配置文件

    <!-- 加载jdbc.properties -->

    <!-- 跑web必须在前面添加classpath:前缀 -->

    <context:property-placeholder location="classpath:jdbc.properties" />

    4.5.9.   再次启动tomcat,没有异常

    4.5.10.        访问http://localhost/product,出现404异常,

    因为没有写jsp页面,此jsp页面和原来写JPA集成Struts2的jsp是一致的。

     

    4.5.11.        product.jsp

    <body>

             <table border="1">

                      <tr>

                               <th>编号</th>

                               <th>产品名称</th>

    <!--                   <th>产品类型名称</th> -->

                               <th>操作</th>

                      </tr>

                      <s:iterator value="#products">

                               <tr>

                                        <td>${id}</td>

                                        <td>${name}</td>

    <%--                                     <td>${dir.name}</td> --%>

                                        <td><a href="product_input?product.id=${id}">修改</a> <a

                                                 href="product_delete?product.id=${id}">删除</a></td>

                               </tr>

                      </s:iterator>

             </table>

             <a href="product_input">添加</a>

    </body>

    1. 以同样的方式添加产品类型

    5.1.  添加产品类型模型

    模型ProductDir,修改Product添加@ManyToOne

    写dao,service

    5.2.  修改web.xml,解决延迟加载的异常

    <!-- 添加关闭entityManger过滤器,必须在struts2过滤器之前 -->

    <filter>

             <filter-name>OpenEntityManagerInViewFilter</filter-name>

             <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>

    </filter>

     

    <filter-mapping>

             <filter-name>OpenEntityManagerInViewFilter</filter-name>

             <url-pattern>/*</url-pattern>

    </filter-mapping>

    1. struts.xml class属性配置原理

    6.1.  struts2加载配置文件顺序

    struts2-core-2.3.20.jarorgapachestruts2default.properties

    struts2-core-2.3.20.jarstruts-default.xml

    struts2-spring-plugin-2.3.20.jarstruts-plugin.xml

    ...

    classpath:struts.xml

    6.2.  struts2-spring-plugin-2.3.20.jar  struts-plugin.xml

    没有使用这个jar文件,struts2的对象创建是由xwork处理

    添加这个这个jar文件之后struts2的对象就由spring创建

    <bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />

       

    <!--  Make the Spring object factory the automatic default -->

    <constant name="struts.objectFactory" value="spring" />

    6.3.  default.properties

    默认情况下在struts.xml的action节点里面class属性写全限定类名是按照byName注入

     

    ### valid values are: name, type, auto, and constructor (name is the default)

    struts.objectFactory.spring.autoWire = name

     

    6.4.  class属性

    6.4.1.   方案1 建议使用,填写spring的bean  id,

    注意xml版本配置scope=’prototype’

        注解版本配置@Scope(“prototype”)

     

    好处1:可以使用小写的url地址,从使用通配符

    <package name="default" namespace="/" extends="struts-default">

     

             <!-- action代表一个控制器, name="对应的访问的url地址" method="返回action的方法" -->

     

             <!-- spring集成struts之后,class可以写全限定类名,也可以写bean.id -->

     

     

    <!-- *_* 请求的url_请求的方法 -->

    <!-- 第1个*代表url地址,比如现在product,后面使用{1}来代替,url地址小写开头,正好对应action的bean.id的定义 -->

    <!-- 第2个*代表访问action的方法,比如现在product_input,后面使用{2}来代替 -->

     

             <action name="*_*" class="{1}Action" method="{2}">

                      <!-- 显示列表页面 -->

                      <result>/WEB-INF/views/{1}.jsp</result>

                      <!-- 显示添加获取修改页面 -->

                      <result name="input">/WEB-INF/views/{1}_input.jsp</result>

                      <!-- 保存或者删除之后进行重定向 -->

                      <result name="reload" type="redirectAction">{1}</result>

             </action>

     

    </package>

     

    好处2:因为使用action是由spring管理

    可以对action添加aop额外处理

     

    坏处:spring配置文件写action的配置

    @Controller//bean.id=productAction

    @Scope("prototype")//配置多例

    public class ProductAction extends ActionSupport {

    6.4.2.   方案2 填写全限定类名,

    如果填写全限定类名,则返回是小写url的地址,要求cn.itsource.ssj.action.ProductAction,类名对应要小写,不符合java命名规范;不能使用*_*通配符

    @Autowired先按照类型,如果接口有2个实现,会报错

    可以添加@Qualifier("productServiceImpl")名称来进行注入

     

    public class ProductAction extends ActionSupport {

             @Autowired

             private IProductService productService;

    1. 课程总结

    7.1.  重点

    Ssj集成必须写熟练,1遍,2遍,3遍

    7.2.  难点

    Spring的配置文件

    <?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.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context.xsd

    http://www.springframework.org/schema/tx

    http://www.springframework.org/schema/tx/spring-tx.xsd">

     

             <!-- jdbc.properties->dataSource->entityManagerFactory->dao->service->junit->action -->

     

             <!-- 扫描dao、service、action组件 -->

             <!-- @Repository, @Service, and @Controller,@Autowired,@PersistenceContext -->

             <context:component-scan base-package="cn.itsource.ssj" />

     

    <!-- 加载jdbc.properties -->

    <!-- 跑web必须在前面添加classpath:前缀 -->

    <context:property-placeholder location="classpath:jdbc.properties" />

     

             <!-- 配置连接池dataSource -->

             <!-- destroy-method="close当前bean销毁的时候,会先调用close方法,关闭连接" -->

             <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

                      <!-- 依赖注入连接池需要的属性 -->

                      <!-- property name="是BasicDataSource的set方法,本质属性" -->

                      <!-- property value="是jdbc.properties配置文件的key" -->

                      <property name="driverClassName" value="${jdbc.driverClassName}" />

                      <property name="url" value="${jdbc.url}" />

                      <property name="username" value="${jdbc.username}" />

                      <property name="password" value="${jdbc.password}" />

             </bean>

     

             <!-- org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter引入默认entityManagerFactory名称 -->

             <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

                      <!-- 1.注入DataSource -->

                      <property name="dataSource" ref="dataSource" />

                      <!-- 2.从哪个包去扫描@Entity,domain包 -->

                      <!-- public void setPackagesToScan(String... packagesToScan) { -->

                      <property name="packagesToScan" value="cn.itsource.ssj.domain" />

                      <!-- 3.配置JPA的实现 -->

                      <!-- private JpaVendorAdapter jpaVendorAdapter; -->

                      <property name="jpaVendorAdapter">

                               <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">

                                        <!-- org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter -->

                                        <!-- private boolean showSql = false;是否显示sql语句 -->

                                        <property name="showSql" value="true" />

                                        <!-- private boolean generateDdl = false;是否建表 -->

                                        <property name="generateDdl" value="true" />

                                        <!-- private String databasePlatform;原来方言 -->

                                        <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />

                               </bean>

                      </property>

             </bean>

     

             <!-- 配置事务管理器 -->

             <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">

                      <property name="entityManagerFactory" ref="entityManagerFactory" />

             </bean>

             <!-- 开启注解事务管理 ,解析@Transactional注解 -->

             <!-- transaction-manager="transactionManager"默认找bean.id=transactionManager事务管理器 -->

             <tx:annotation-driven />

     

     

    </beans>

    1. 常见异常
    2. javax.persistence.TransactionRequiredException: No transactional EntityManager available

    事务没有配置成功

    没有配置<tx:annotation-driven />

    1. No qualifying bean of type [cn.itsource.ssj.service.IProductService] is defined: expected single matching bean but found 2: productServiceImpl,productServiceImpl2

    Could not autowire field: private cn.itsource.ssj.service.IProductService cn.itsource.ssj.action.ProductAction.productService; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of

    type [cn.itsource.ssj.service.IProductService] is defined: expected single matching bean but found 2: productServiceImpl,productServiceImpl2

    接口有2个实现

  • 相关阅读:
    【原】为什么选择iPhone5的分辨率作为H5视觉稿尺寸
    js 进制转换
    抓包 抓nodejs的包 抓浏览器的包 抓手机的包
    nginx 安装 ssl 证书
    github 被强了!太丧心病狂了!
    yandex 图片自动下载
    如何获取命令行的原始参数?
    npm 加速之 yarn cnpm pnpm
    json 格式化处理工具
    两分钟观看 nodejs、 iojs、 npmjs 之间的狗血剧情
  • 原文地址:https://www.cnblogs.com/Src-z/p/11218908.html
Copyright © 2020-2023  润新知