Spring 3.1 JPA在tomcat中运行时未插入数据 [英] Spring 3.1 JPA not inserting data while running in tomcat

查看:67
本文介绍了Spring 3.1 JPA在tomcat中运行时未插入数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了三天的时间试图找到解决该问题的方法,但无济于事.我很想弄清楚这一点.我有一个简单的spring应用程序,它在带有jstl标签1.2的servlet 2.5中运行,在使用spring 3.1的tomcat中运行,并使用了hibernate和hibernate jpa实现.

我可以列出页面中的数据,但无法完成插入.记录可以追溯,它似乎没有任何问题.但是没有插入发生.我知道还有其他类似的帖子,但是我已经仔细阅读了所有这些帖子,却无法在任何地方找到解决方案.

如果我通过MAIN类运行完全相同的代码,则插入工作正常.在tomcat中作为Web应用程序运行时,它只是不起作用.

我试图通过有效的主程序来运行它,在控制器内部,我跳过了调用服务层的尝试,尝试直接进入接口,如果不起作用,我尝试直接进入实现DAO类,并且没有工作.通过spring日志显示,正在创建实体管理器,并在发生事务之前将其关闭.

请帮助我.

这是我的应用环境

            <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:aop="http://www.springframework.org/schema/aop" 
                    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.0.xsd 
                    http://www.springframework.org/schema/context 
                    http://www.springframework.org/schema/context/spring-context-3.0.xsd 
                    http://www.springframework.org/schema/tx 
                    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
                    http://www.springframework.org/schema/aop 
                    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" 
                    default-autowire="byName">

                <context:component-scan base-package="com.naturalbornliar.site"/>
                <tx:annotation-driven />
                <!-- Bean declarations go here-->

                <bean id="duke" class="com.naturalbornliar.site.entity.Admin">
                    <constructor-arg name="admin_id" type="Long" value="15" />
                    <constructor-arg name="admin_login" type="String" value="testUser" />
                    <constructor-arg name="admin_pwd" type="String" value="testPwd" />
                    <constructor-arg name="email_id" type="int" value="15" />
                    <constructor-arg name="quote" type="String" value="Something to say here" />    
                </bean>

            <!--    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> -->
            <!--        <property name="driverClassName" value="com.mysql.jdbc.Driver"/> -->
            <!--        <property name="url" value="jdbc:mysql://localhost:3306/nbl_db"/> -->
            <!--        <property name="username" value="web_user"/> -->
            <!--        <property name="password" value="web_pwd"/> -->
            <!--        <property name="initialSize" value="5"/> -->
            <!--        <property name="maxActive" value="10"/> -->
            <!--    </bean> -->

                <bean id="simpledataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/nbl_db"/>
                    <property name="username" value="web_user"/>
                    <property name="password" value="web_pwd"/>
                </bean>

                <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
                    <constructor-arg ref="simpledataSource"/>
                </bean>

                <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
                    <property name="persistenceUnitName" value="nblPersistenceUnit"/>
                    <property name="dataSource" ref="simpledataSource"/>
                    <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
                </bean>

            <!--    <bean id="emf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"> -->
            <!--        <property name="persistenceUnitName" value="nblPersistenceUnit"/> -->
            <!--        <property name="dataSource" ref="simpledataSource"/>-->
            <!--        <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/> -->
            <!--    </bean> -->

                <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
                    <property name="entityManagerFactory" ref="emf"/>
                    <property name="jpaDialect" ref="jpaDialect"/>
                </bean>

                <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>

                <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                    <property name="database" value="MYSQL"/>
                    <property name="showSql" value="true"/>
                    <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>
                </bean>

                <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

                <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

                <tx:advice id="txAdvice">
                    <tx:attributes>
                        <tx:method name="add*" propagation="REQUIRED"/>
                        <tx:method name="delete*" propagation="REQUIRED"/>
                        <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
                    </tx:attributes>
                </tx:advice>

                <aop:config>

                    <aop:advisor pointcut="execution(* *..CategoryDaoImpl.*(..))" advice-ref="txAdvice"/>

                </aop:config>

                </beans>

这是我的控制人:

            package com.naturalbornliar.site.mvc;

            import javax.inject.Inject;

            import org.apache.log4j.Logger;
            import org.springframework.stereotype.Controller;
            import org.springframework.ui.Model;
            import org.springframework.validation.BindingResult;
            import org.springframework.web.bind.annotation.RequestMapping;
            import org.springframework.web.bind.annotation.RequestMethod;

            import com.naturalbornliar.site.entity.Category;
            import com.naturalbornliar.site.entity.Link;
            import com.naturalbornliar.site.service.CategoryService;


            @Controller
            @RequestMapping("/categories")
            public class CategoryController {


                protected final Logger logger = Logger.getLogger(CategoryController.class);

                private final CategoryService categoryService;

                @Inject
                public CategoryController(CategoryService categoryService){
                    this.categoryService = categoryService;
                }

                @RequestMapping(value="/listCategories")
                public String listLinks(Model model){

                    model.addAttribute("categories", categoryService.getAllCategories());

                    return "categories";
                }

                @RequestMapping(method=RequestMethod.GET, params="new")
                public String showCreateCategoryForm(Model model){
                    model.addAttribute(new Category());
                    return "addcategory";
                }

                @RequestMapping(method=RequestMethod.POST)
                public String addCategoryFromForm(Category category, BindingResult bindingResult){
                    if(bindingResult.hasErrors()){
                        return"addcategory";
                        }
                    categoryService.addCategory(category);
                    return "redirect:/categories/listCategories";
                }
            }

这是我从控制器调用的服务:

            package com.naturalbornliar.site.service;

            import java.util.Collection;

            import javax.inject.Inject;

            import org.springframework.stereotype.Service;

            import com.naturalbornliar.site.entity.Category;
            import com.naturalbornliar.site.i.ICategoryDao;

            @Service
            public class CategoryService {

                private ICategoryDao iCategoryDao;

                @Inject
                public CategoryService(ICategoryDao iCategoryDao){
                    this.iCategoryDao = iCategoryDao;
                }

                public Collection<Category> getAllCategories(){
                    return iCategoryDao.getAllCategories();
                }

                public Collection<Category> getCategoriesByType(String type) {
                    return iCategoryDao.getCategoriesByType(type);
                }

                public Category getCategoryById(Long id) {
                    throw new UnsupportedOperationException();
                }

                public void deleteCategory(Category category) {
                    throw new UnsupportedOperationException();
                }

                public void updateCategory(Category category) {
                    throw new UnsupportedOperationException();
                }

                public void inactivateCategory(Category category){
                    throw new UnsupportedOperationException();
                }

                public void addCategory(Category category){
                    iCategoryDao.addCategory(category);
                }
            }

这是我正在实施的DAO:

            package com.naturalbornliar.site.dao;

            import java.util.Collection;
            import java.util.List;

            import javax.persistence.EntityManager;
            import javax.persistence.PersistenceContext;

            import org.apache.log4j.Logger;
            import org.springframework.stereotype.Repository;
            import org.springframework.transaction.annotation.Transactional;

            import com.naturalbornliar.site.entity.Content;
            import com.naturalbornliar.site.i.IContentDao;

            @Transactional
            @Repository
            public class ContentDaoImpl implements IContentDao {

                protected final Logger logger = Logger.getLogger(ContentDaoImpl.class);

                @PersistenceContext
                private EntityManager em;

                public EntityManager getEm() {
                    return em;
                }


                public void setEm(EntityManager em) {
                    this.em = em;
                }

                @Override
                public void addContent(Content content) {
                    // TODO Auto-generated method stub
                    em.persist(content);
                }

                @Override
                public void deleteContent(Content content) {
                    // TODO Auto-generated method stub
                    em.remove(content);

                }

                @Override
                public void inactivateContent(Content content) {
                    // TODO Auto-generated method stub

                }

                @Override
                public Content getContentById(Long id) {
                    // TODO Auto-generated method stub
                    return null;
                }

                @Override
                public Content getContentByName(String name) {
                    // TODO Auto-generated method stub
                    return null;
                }

                @Override
                public Collection<Content> getAllObjects() {
                    List<Content> resultList = em.createQuery("FROM Content", Content.class).getResultList();
                    return resultList;
                }

            }

这里是界面(以防万一)

            package com.naturalbornliar.site.i;

            import java.util.Collection;

            import com.naturalbornliar.site.entity.Content;

            public interface IContentDao {

                public void addContent(Content content);
                public void deleteContent(Content content);
                public void inactivateContent(Content content);
                public Content getContentById(Long id);
                public Content getContentByName(String name);
                public Collection<Content> getAllObjects();

            }

解决方案

我实际上已经解决了这个问题.这是解决方案,还有一个解决该问题的stackoverflow问题:

Spring @Transaction无法开始交易

基本上,为使交易能够正确触发,我需要添加:

<tx:annotation-driven proxy-target-class="true"/>

到我的servlet xml.我想如果您仅将它放在应用程序config.xml中,则它仅在主类下运行时才起作用(例如在独立类中),如果您需要在容器中运行它,则还必须在Servlet中声明事务注释. /p>

I have spent three days trying to find the solution to this problem to no avail. I am desperate to figure this out. I have a simple spring app, running in servlet 2.5 with jstl tags 1.2, running in tomcat with spring 3.1, using hibernate and the hibernate jpa implementation.

I can list data from a page, but I cannot complete an insert. The record goes back, it appears to fire through with no problems. Yet no insert takes place. I know there are other posts similar but I have looked through them all and have not been able to find a solution anywhere.

If I run the exact same code via a MAIN class, the insert works fine. It just does not work when running as a web-app in tomcat.

I have tried running this via the main which works, inside the controller I have skipped calling the service layer, trying to go directly to the interface, when that didnt work, I tried going directly to the implementing DAO class, and that didnt work. It appears via the spring logs, that the entity manager is getting created, and shut down before a transaction takes place.

Please help me.

Here is my App-context

            <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:aop="http://www.springframework.org/schema/aop" 
                    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.0.xsd 
                    http://www.springframework.org/schema/context 
                    http://www.springframework.org/schema/context/spring-context-3.0.xsd 
                    http://www.springframework.org/schema/tx 
                    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
                    http://www.springframework.org/schema/aop 
                    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" 
                    default-autowire="byName">

                <context:component-scan base-package="com.naturalbornliar.site"/>
                <tx:annotation-driven />
                <!-- Bean declarations go here-->

                <bean id="duke" class="com.naturalbornliar.site.entity.Admin">
                    <constructor-arg name="admin_id" type="Long" value="15" />
                    <constructor-arg name="admin_login" type="String" value="testUser" />
                    <constructor-arg name="admin_pwd" type="String" value="testPwd" />
                    <constructor-arg name="email_id" type="int" value="15" />
                    <constructor-arg name="quote" type="String" value="Something to say here" />    
                </bean>

            <!--    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> -->
            <!--        <property name="driverClassName" value="com.mysql.jdbc.Driver"/> -->
            <!--        <property name="url" value="jdbc:mysql://localhost:3306/nbl_db"/> -->
            <!--        <property name="username" value="web_user"/> -->
            <!--        <property name="password" value="web_pwd"/> -->
            <!--        <property name="initialSize" value="5"/> -->
            <!--        <property name="maxActive" value="10"/> -->
            <!--    </bean> -->

                <bean id="simpledataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/nbl_db"/>
                    <property name="username" value="web_user"/>
                    <property name="password" value="web_pwd"/>
                </bean>

                <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
                    <constructor-arg ref="simpledataSource"/>
                </bean>

                <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
                    <property name="persistenceUnitName" value="nblPersistenceUnit"/>
                    <property name="dataSource" ref="simpledataSource"/>
                    <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
                </bean>

            <!--    <bean id="emf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"> -->
            <!--        <property name="persistenceUnitName" value="nblPersistenceUnit"/> -->
            <!--        <property name="dataSource" ref="simpledataSource"/>-->
            <!--        <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/> -->
            <!--    </bean> -->

                <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
                    <property name="entityManagerFactory" ref="emf"/>
                    <property name="jpaDialect" ref="jpaDialect"/>
                </bean>

                <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>

                <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                    <property name="database" value="MYSQL"/>
                    <property name="showSql" value="true"/>
                    <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>
                </bean>

                <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

                <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

                <tx:advice id="txAdvice">
                    <tx:attributes>
                        <tx:method name="add*" propagation="REQUIRED"/>
                        <tx:method name="delete*" propagation="REQUIRED"/>
                        <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
                    </tx:attributes>
                </tx:advice>

                <aop:config>

                    <aop:advisor pointcut="execution(* *..CategoryDaoImpl.*(..))" advice-ref="txAdvice"/>

                </aop:config>

                </beans>

Here is my controller:

            package com.naturalbornliar.site.mvc;

            import javax.inject.Inject;

            import org.apache.log4j.Logger;
            import org.springframework.stereotype.Controller;
            import org.springframework.ui.Model;
            import org.springframework.validation.BindingResult;
            import org.springframework.web.bind.annotation.RequestMapping;
            import org.springframework.web.bind.annotation.RequestMethod;

            import com.naturalbornliar.site.entity.Category;
            import com.naturalbornliar.site.entity.Link;
            import com.naturalbornliar.site.service.CategoryService;


            @Controller
            @RequestMapping("/categories")
            public class CategoryController {


                protected final Logger logger = Logger.getLogger(CategoryController.class);

                private final CategoryService categoryService;

                @Inject
                public CategoryController(CategoryService categoryService){
                    this.categoryService = categoryService;
                }

                @RequestMapping(value="/listCategories")
                public String listLinks(Model model){

                    model.addAttribute("categories", categoryService.getAllCategories());

                    return "categories";
                }

                @RequestMapping(method=RequestMethod.GET, params="new")
                public String showCreateCategoryForm(Model model){
                    model.addAttribute(new Category());
                    return "addcategory";
                }

                @RequestMapping(method=RequestMethod.POST)
                public String addCategoryFromForm(Category category, BindingResult bindingResult){
                    if(bindingResult.hasErrors()){
                        return"addcategory";
                        }
                    categoryService.addCategory(category);
                    return "redirect:/categories/listCategories";
                }
            }

Here is my service called from the controller:

            package com.naturalbornliar.site.service;

            import java.util.Collection;

            import javax.inject.Inject;

            import org.springframework.stereotype.Service;

            import com.naturalbornliar.site.entity.Category;
            import com.naturalbornliar.site.i.ICategoryDao;

            @Service
            public class CategoryService {

                private ICategoryDao iCategoryDao;

                @Inject
                public CategoryService(ICategoryDao iCategoryDao){
                    this.iCategoryDao = iCategoryDao;
                }

                public Collection<Category> getAllCategories(){
                    return iCategoryDao.getAllCategories();
                }

                public Collection<Category> getCategoriesByType(String type) {
                    return iCategoryDao.getCategoriesByType(type);
                }

                public Category getCategoryById(Long id) {
                    throw new UnsupportedOperationException();
                }

                public void deleteCategory(Category category) {
                    throw new UnsupportedOperationException();
                }

                public void updateCategory(Category category) {
                    throw new UnsupportedOperationException();
                }

                public void inactivateCategory(Category category){
                    throw new UnsupportedOperationException();
                }

                public void addCategory(Category category){
                    iCategoryDao.addCategory(category);
                }
            }

Here is my implementing DAO:

            package com.naturalbornliar.site.dao;

            import java.util.Collection;
            import java.util.List;

            import javax.persistence.EntityManager;
            import javax.persistence.PersistenceContext;

            import org.apache.log4j.Logger;
            import org.springframework.stereotype.Repository;
            import org.springframework.transaction.annotation.Transactional;

            import com.naturalbornliar.site.entity.Content;
            import com.naturalbornliar.site.i.IContentDao;

            @Transactional
            @Repository
            public class ContentDaoImpl implements IContentDao {

                protected final Logger logger = Logger.getLogger(ContentDaoImpl.class);

                @PersistenceContext
                private EntityManager em;

                public EntityManager getEm() {
                    return em;
                }


                public void setEm(EntityManager em) {
                    this.em = em;
                }

                @Override
                public void addContent(Content content) {
                    // TODO Auto-generated method stub
                    em.persist(content);
                }

                @Override
                public void deleteContent(Content content) {
                    // TODO Auto-generated method stub
                    em.remove(content);

                }

                @Override
                public void inactivateContent(Content content) {
                    // TODO Auto-generated method stub

                }

                @Override
                public Content getContentById(Long id) {
                    // TODO Auto-generated method stub
                    return null;
                }

                @Override
                public Content getContentByName(String name) {
                    // TODO Auto-generated method stub
                    return null;
                }

                @Override
                public Collection<Content> getAllObjects() {
                    List<Content> resultList = em.createQuery("FROM Content", Content.class).getResultList();
                    return resultList;
                }

            }

Here is the interface (just in case)

            package com.naturalbornliar.site.i;

            import java.util.Collection;

            import com.naturalbornliar.site.entity.Content;

            public interface IContentDao {

                public void addContent(Content content);
                public void deleteContent(Content content);
                public void inactivateContent(Content content);
                public Content getContentById(Long id);
                public Content getContentByName(String name);
                public Collection<Content> getAllObjects();

            }

解决方案

Well I actually solved the problem. Here is the solution, there was another stackoverflow issue that solved it:

Spring @Transaction not starting transactions

Basically all that was needed for transactions to fire correctly was for me to add:

<tx:annotation-driven proxy-target-class="true"/>

to my servlet xml. I guess if you just have it in the application config.xml it only works when running under the main class (like in a standalone) if you need to run it in a container you have to declare transaction annotations in the servlet as well.

这篇关于Spring 3.1 JPA在tomcat中运行时未插入数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆