我是春天的新人。最近我一直试图使用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
。那我怎么能有活跃的实体交易参考?我应该怎么做提交或回滚?