spring + jpa + hibernate 不能增删改

Ping_QC 发布于 2012/06/20 16:32
阅读 14K+
收藏 1

这个是applicationContext.xml内容:

<?xml version="1.0" encoding="UTF-8"?>
<beans (节省空间)default-lazy-init="true">

    <description>Spring公共配置 </description>

    <!-- 使用annotation 自动注册bean, 并保证@Required、@Autowired的属性被注入 -->
    <context:component-scan base-package="com.pqc.tbk">
<!-- <context:exclude-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />-->
    </context:component-scan>

    <!-- Jpa Entity Manager 配置 -->
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="persistenceUnitName" value="pqc-tbk" />
        <property name="persistenceProvider" ref="persistenceProvider"/>
        <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.max_fetch_depth">3</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.jdbc.fetch_size">18</prop>
                <prop key="hibernate.jdbc.batch_size">10</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">false</prop>
                <!-- 
                <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
                </prop>
                <prop key="net.sf.ehcache.configurationResourceName">ehcache/ehcache-hibernate-local.xml</prop>
                <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
                -->
            </props>
        </property>
    </bean>

    <bean id="persistenceProvider" class="org.hibernate.ejb.HibernatePersistence"/>

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

    <!-- Jpa 事务配置 -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <!-- 使用annotation定义事务 -->
    <tx:annotation-driven transaction-manager="transactionManager"
        proxy-target-class="true" />

    <bean
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
        <property name="ignoreResourceNotFound" value="true" />
        <property name="locations">
            <list>
                <!-- 标准配置 -->
                <value>classpath*:/application.properties</value>
                <!-- 本地开发环境配置 
                <value>classpath*:/application.local.properties</value>-->
                <!-- 服务器生产环境配置 
                <value>file:/var/mini-web/application.server.properties</value>-->
            </list>
        </property>
    </bean>

    <!-- 数据源配置,使用应用内的DBCP数据库连接池 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close" lazy-init="false">
        <!-- Connection Info -->
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />

        <!-- Connection Pooling Info -->
        <property name="maxIdle" value="${dbcp.maxIdle}" />
        <property name="maxActive" value="${dbcp.maxActive}" />
        <property name="defaultAutoCommit" value="false" />
        <property name="timeBetweenEvictionRunsMillis" value="3600000" />
        <property name="minEvictableIdleTimeMillis" value="3600000" />
    </bean>

</beans>

这个是persistence.xml

<persistence-unit name="pqc-tbk" transaction-type="RESOURCE_LOCAL">
    <mapping-file>META-INF/orm.xml</mapping-file>
</persistence-unit>

orm.xml

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm/orm_2_0.xsd" version="2.0">
</entity-mappings>

//UserDaoImpl.jav
@Repository
public class UserDaoImpl implements UserDao {

    private EntityManager em;

    @Override
    public boolean checkLogin(final String username, final String password) {
        final Long n = em.createQuery(
            "select count(*)from User where username = ? and password = ?",Long.class).
            setParameter(1, username).
            setParameter(2, password).
            getSingleResult();
        return n != 0L;
    }

    @Override
    public void delete(final Long id) {
        em.createQuery("delete from User where id = " + id).executeUpdate();
    }

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

 UserServiceImpl.java

@Service 
@Transactional(readOnly = false)
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    public void test() {
        userDao.checkLogin("admin", "admin");
        userDao.delete(1L));
    }
}

错误是:

javax.persistence.TransactionRequiredException: Executing an update/delete query

这边我看到:

“javax.persistence.TransactionRequiredException:Executing an update/delete query:表示没有事务支持,不能执行更新或删除操作;

但是我不是已经加了事务吗?

还是说我的配置有问题,谢谢

加载中
2
laugh2last
laugh2last

Spring MVC最打击新人的事情,你必须保证spring-mvc.xml的<context:component-scan>只扫描Controller,而 applicationContext.xml里的不包含Controller。否则你定义在applicationContext.xml里的事务就要失效了。

详见:springside online ref

https://github.com/springside/springside4/wiki/SpringMVC

2
joock
joock

希望遇到问题的同学能翻到这一页,同样碰到这个问题2次,问题每次都解决了 ,但是由于项目进度的原因出问题的原因一直没找到,记录在此,希望能给其他同学一些启发吧。

前提:

使用了spring data jpa使用了load time weaving。

问题:

第一次:cxf生成的stub导致的问题

第二次:@Query里jpql写的错误导致的问题

分析:

推测问题应该是由于dispatcher-servlet.xml将service层的代码扫描进了spring容器,但是没有weaving进去事务的代码导致的,希望有同学能基于这个思路继续分析一下。

感谢楼上各位,提供了思路~ oschina的回复质量还是可以的  :D


1
唐代de豆腐
唐代de豆腐

我也遇到这个问题了,哈哈。。搞了好久还搞不定。我单纯的curd没问题。但是。

@Modifying
    @Query("delete from Authority t where t.role.id=:roleId")
    public int delRoleAuthority(@Param("roleId") String roleId);
这个东西就有问题了。

我在service调这个。并且加了

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

还是报错。没有事务 。我无语了。

micical
micical
同样的问题,求解决方案
1
firnice
firnice

引用来自“laugh2last”的答案

Spring MVC最打击新人的事情,你必须保证spring-mvc.xml的<context:component-scan>只扫描Controller,而 applicationContext.xml里的不包含Controller。否则你定义在applicationContext.xml里的事务就要失效了。

详见:springside online ref

https://github.com/springside/springside4/wiki/SpringMVC

这个能解决我的问题~
1
一代码农

引用来自“firnice”的答案

引用来自“laugh2last”的答案

Spring MVC最打击新人的事情,你必须保证spring-mvc.xml的<context:component-scan>只扫描Controller,而 applicationContext.xml里的不包含Controller。否则你定义在applicationContext.xml里的事务就要失效了。

详见:springside online ref

https://github.com/springside/springside4/wiki/SpringMVC

这个能解决我的问题~
+1
0
Ping_QC
Ping_QC
怎么问了个jpa的问题都没有人回答啊?
0
刘健
刘健
求解,我也遇到这个问题,我用的是Spring data jpa
Ping_QC
Ping_QC
我是从用spring data jpa 的一个项目中拷出来的,把spring data 给去掉了
0
aviation
aviation
如果你用的mysql的非innodb引擎是不支持事务的。。不知道是不是这个原因? 我记得有个属性是要在配置文件里面申明的(如果要使用标签的话)
Ping_QC
Ping_QC
你好,试过了 ,不是引擎的问题
0
lixuenong
lixuenong
@Transactional(readOnly = false )
0
刘健
刘健

引用来自“lixuenong”的答案

@Transactional(readOnly = false )
这个是有加的,奇怪的是这个事务管理是不起作用的,而且Spring data Jpa默认是使用事务的
返回顶部
顶部