无法提交JPA交易;合并实体时嵌套异常是javax.persistence.RollbackException

时间:2016-10-15 10:03:24

标签: java spring hibernate spring-mvc jpa

我是春天的新人。最近我一直试图使用spring JPA和hibernate来连接数据库并插入数据。

我可以将实体插入数据库,但我无法删除它们。

我创建了一个抽象的主DAO,我的所有DAO都必须扩展它,并在需要时单独添加新方法。

然后有一个shopDao课程,所有关于购物系统的DAO都延伸了这个。

作为一个例子,有一个LanguageDao应该在LanguageEntity上做事务。

这是我的代码:

AbstractDao的

@Component
@Repository
@Transactional(rollbackFor = Exception.class)
public abstract class AbstractPgsqlDao<E> implements Dao<E> {
    protected EntityManager em;
    protected String entityClassName;

    protected void init(){
        entityClassName = this.getClass().getName().substring(this.getClass().getName().lastIndexOf(".")+1).trim().replace("Pgsql","").replace("Dao","Entity");
    }

    public EntityManager getEntityManager() {
        return em;
    }


    @Override
    public void insert(E entity) throws Exception {
            em.persist(entity);
    }

    @Override
    public void remove(E entity) {
        em.remove(entity);
    }

    @Override
    public void remove(long id) {
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        String query = String.format("DELETE FROM %s table WHERE table.id= :id", entityClassName);
        Query jpaQuery = em.createQuery(query);
        jpaQuery.setParameter("id", id).executeUpdate();
        tx.commit();
    }

    @Override
    public void update(E entity) throws EntityNotFoundException {
        em.merge(entity);
    }

    @Override
    public List selectAll() {
        String query = String.format("SELECT table FROM %s table ", entityClassName);
        Query jpaQuery = em.createQuery(query);
        List resultList = jpaQuery.getResultList();
        return resultList;
    }

    @Override
    public List selectAll(String sort) {
        String query = String.format("SELECT table FROM %s table ORDER BY table." + sort, entityClassName);
        Query jpaQuery = em.createQuery(query);
        List resultList = jpaQuery.getResultList();
        return resultList;
    }

    @Override
    public E find(long id) {
        String query = String.format("SELECT table FROM %s table WHERE table.id = :id", entityClassName);
        Query jpaQuery = em.createQuery(query);
        jpaQuery.setParameter("id", Integer.parseInt(String.valueOf(id)));
        E result = (E) jpaQuery.getSingleResult();
        return result;
    }
}

AbstractShopPgsqlDao

@Component
@Transactional(noRollbackFor = Exception.class)
public class AbstractShopPgsqlDao<E> extends AbstractPgsqlDao<E> implements Dao<E> {
    public AbstractShopPgsqlDao() {
        init();
    }

    @Override
    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.em = entityManager;
    }
}

PgsqlLanguageDao

@Component
public class PgsqlLanguageDao extends AbstractShopPgsqlDao<LanguageEntity> implements LanguageDao {

}

LanguageEntity

@Entity
@Table(name = "language")
public class LanguageEntity {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    @Column
    private int id;

    @Column
    private String name;

    @Column
    private String locale;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLocale() {
        return locale;
    }

    public void setLocale(String locale) {
        this.locale = locale;
    }
}

MVC-调度

   <!-- This produces a container-managed EntityManagerFactory;
         rather than application-managed EntityManagerFactory as in case of LocalEntityManagerFactoryBean-->
    <bean id="entityManagerFactoryBean" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- This makes /META-INF/persistence.xml is no longer necessary -->
        <property name="packagesToScan" value="com.easyshop.domain.entity"/>
        <!-- JpaVendorAdapter implementation for Hibernate EntityManager.
               Exposes Hibernate's persistence provider and EntityManager extension interface -->
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">validate</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL82Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.connection.characterEncoding">UTF-8</prop>
                <prop key="hibernate.connection.useUnicode">true</prop>
            </props>
        </property>
    </bean>

    <!-- Simple implementation of the standard JDBC DataSource interface,
            configuring the plain old JDBC DriverManager via bean properties -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.postgresql.Driver"/>
        <property name="url" value="jdbc:postgresql://localhost/shop"/>
        <property name="username" value="user"/>
        <property name="password" value="pass"/>
    </bean>

    <!-- This transaction manager is appropriate for applications that use a single JPA EntityManagerFactory for transactional data access.
        JTA (usually through JtaTransactionManager) is necessary for accessing multiple transactional resources within the same transaction. -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactoryBean"/>
    </bean>

所以我可以在数据库中插入一些语言,但我无法更新一个。 我试试

LanguageEntity languageEntity = languageDao.find(2);
System.out.println(languageEntity.getName());
languageEntity.setName("English");
languageEntity.setLocale("EN");
languageDao.update(languageEntity);

在我的控制器中,但这是我得到的错误:

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy193.update(Unknown Source)
    at com.easyshop.controller.HomeController.test2(HomeController.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at com.easyshop.filter.DisableUrlSessionFilter.doFilter(DisableUrlSessionFilter.java:38)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at com.easyshop.filter.BaseUrlFilter.doFilter(BaseUrlFilter.java:27)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:957)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javax.persistence.RollbackException: Error while committing the transaction
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:90)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:512)
    ... 56 more
Caused by: java.lang.NullPointerException
    at org.hibernate.ejb.event.EJB3PostUpdateEventListener.handlePostUpdate(EJB3PostUpdateEventListener.java:71)
    at org.hibernate.ejb.event.EJB3PostUpdateEventListener.onPostUpdate(EJB3PostUpdateEventListener.java:67)
    at org.hibernate.action.internal.EntityUpdateAction.postUpdate(EntityUpdateAction.java:259)
    at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:206)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:395)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:387)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:304)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:349)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1159)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:73)
    ... 57 more

最后一个根本原因:

java.lang.NullPointerException
    org.hibernate.ejb.event.EJB3PostUpdateEventListener.handlePostUpdate(EJB3PostUpdateEventListener.java:71)
    org.hibernate.ejb.event.EJB3PostUpdateEventListener.onPostUpdate(EJB3PostUpdateEventListener.java:67)
    org.hibernate.action.internal.EntityUpdateAction.postUpdate(EntityUpdateAction.java:259)
    org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:206)
    org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:395)
    org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:387)
    org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:304)
    org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:349)
    org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
    org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1159)
    org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
    org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
    org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:73)
    org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerSynchronization.afterCommit(ExtendedEntityManagerCreator.java:478)
    org.springframework.transaction.support.TransactionSynchronizationUtils.invokeAfterCommit(TransactionSynchronizationUtils.java:133)
    org.springframework.transaction.support.TransactionSynchronizationUtils.triggerAfterCommit(TransactionSynchronizationUtils.java:121)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerAfterCommit(AbstractPlatformTransactionManager.java:950)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:796)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    com.sun.proxy.$Proxy498.update(Unknown Source)
    com.easyshop.controller.HomeController.test2(HomeController.java:48)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    com.easyshop.filter.DisableUrlSessionFilter.doFilter(DisableUrlSessionFilter.java:38)
    com.easyshop.filter.BaseUrlFilter.doFilter(BaseUrlFilter.java:27)
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

我已经在互联网上搜索过,我尝试了@transactional的rollbackFor parameteres但是对我不起作用!谁能告诉我代码中有什么问题?

另外,我无法使用em.getTransaction()启动交易(肯定remove()无效),我得到Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead。那我怎么能有活跃的实体交易参考?我应该怎么做提交或回滚?

0 个答案:

没有答案