Java entitymanager persist 不保存到数据库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22664681/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
entitymanager persist does not save to database
提问by Dhorium
I'm currently facing a problem when trying to save to my database using the persist method from an entitymanager. When executing it, it does not produce an exception but it doesn't save the object to my database. Reading objects that were inserted manually does work.
我目前在尝试使用实体管理器中的持久方法保存到我的数据库时遇到问题。执行它时,它不会产生异常,但不会将对象保存到我的数据库中。读取手动插入的对象确实有效。
GenericDAOImpl
通用DAOImpl
package be.greg.PaymentDatabase.DAO;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;
public abstract class GenericDaoImpl<T> implements GenericDao<T> {
@PersistenceContext
protected EntityManager em;
private Class<T> type;
String entity;
@SuppressWarnings({ "unchecked", "rawtypes" })
public GenericDaoImpl() {
Type t = getClass().getGenericSuperclass();
ParameterizedType pt = (ParameterizedType) t;
type = (Class) pt.getActualTypeArguments()[0];
}
@Override
public long countAll(final Map<String, Object> params) {
final StringBuffer queryString = new StringBuffer(
"SELECT count(o) from ");
queryString.append(type.getSimpleName()).append(" o ");
// queryString.append(this.getQueryClauses(params, null));
final Query query = this.em.createQuery(queryString.toString());
return (Long) query.getSingleResult();
}
@Override
@Transactional
public T create(final T t) {
this.em.persist(t);
return t;
}
@Override
public void delete(final Object id) {
this.em.remove(this.em.getReference(type, id));
}
@Override
public T find(final Object id) {
return (T) this.em.find(type, id);
}
@Override
public T update(final T t) {
return this.em.merge(t);
}
@SuppressWarnings("unchecked")
@Override
@Transactional
public List<T> findAll() {
Query query = em.createQuery("select x from " + getEntityName() + " x");
return (List<T>) query.getResultList();
}
public String getEntityName() {
if (entity == null) {
Entity entityAnn = (Entity) type.getAnnotation(Entity.class);
if (entityAnn != null && !entityAnn.name().equals("")) {
entity = entityAnn.name();
} else {
entity = type.getSimpleName();
}
}
return entity;
}
}
AuthorizationV2DAOImpl
授权V2DAOImpl
package be.greg.PaymentDatabase.DAO;
import org.springframework.stereotype.Repository;
import be.greg.PaymentDatabase.model.Authorization;
@Repository
public class AuthorizationV2DAOImpl extends GenericDaoImpl<Authorization>
implements AuthorizationV2DAO {
}
AuthorizationService
授权服务
package be.greg.PaymentDatabase.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import be.greg.PaymentDatabase.DAO.AuthorizationV2DAOImpl;
import be.greg.PaymentDatabase.model.Authorization;
@Service
public class AuthorizationService {
@Autowired
private AuthorizationV2DAOImpl authorizationDAO;
public Authorization getAuthorization(int id){
return authorizationDAO.find(id);
}
public List<Authorization> getAllAuthorizations(){
return authorizationDAO.findAll();
}
public void createAuthorization(Authorization authorization)
{
authorizationDAO.create(authorization);
}
}
Authorization
授权
package be.greg.PaymentDatabase.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "authorization")
public class Authorization {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(length = 32, nullable = false)
private String clientId;
@Column(length = 32, nullable = false)
private String acquiringInstitutionId;
@Column(length = 32, nullable = false)
private String cardAcceptorTerminalId;
@Column(length = 32, nullable = false)
private String merchantTransactionTimestamp;
@Column(length = 32, nullable = false)
private String industry;
@Column(length = 32, nullable = false)
private String accountNumber;
@Column(nullable = false)
private boolean maskedAccount;
@Column(length = 11, nullable = false)
private int expiryMonth;
@Column(length = 11, nullable = false)
private int expiryYear;
@Column(length = 32, nullable = false)
private String securityCode;
@Column(length = 32, nullable = false)
private String line1;
@Column(length = 32, nullable = true)
private String line2;
@Column(length = 32, nullable = true)
private String city;
@Column(length = 32, nullable = true)
private String countrySubdivision;
@Column(length = 32, nullable = false)
private String postalCode;
@Column(length = 32, nullable = false)
private String country;
@Column(length = 32, nullable = false)
private String clientReference;
@Column(length = 32, nullable = false)
private String currency;
@Column(length = 11, nullable = false)
private int value;
@Column(length = 32, nullable = false)
private String ecommerceIndicator;
@Column(length = 32, nullable = false)
private String transactionId;
@Column(length = 32, nullable = false)
private String token;
Constructor, getters and setters ...
spring-context.xml
spring-context.xml
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
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.2.xsd">
<context:component-scan base-package="be.greg.PaymentDatabase" />
<mvc:annotation-driven />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="jdbcPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:project.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}"
p:username="${jdbc.username}" />
<bean id="persistenceUnitManager"
class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>classpath*:META-INF/persistence.xml</value>
</list>
</property>
<property name="defaultDataSource" ref="dataSource" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="persistenceUnitName" value="entityManager" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
persistance.xml
持久性.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="entityManager"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<validation-mode>NONE</validation-mode>
<class>be.greg.PaymentDatabase.model.Authorization</class>
<class>be.greg.PaymentDatabase.model.AuthorizationResponse</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="false" />
</properties>
</persistence-unit>
</persistence>
hibernate.cfg.xml
休眠文件.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/paymentdatabase?zeroDateTimeBehavior=convertToNull</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping class="be.greg.PaymentDatabase.model.Authorization" />
<mapping class="be.greg.PaymentDatabase.model.AuthorizationResponse" />
</session-factory>
</hibernate-configuration>
runnable main class
可运行的主类
package be.greg.PaymentDatabase.Tests;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import be.greg.PaymentDatabase.model.Authorization;
import be.greg.PaymentDatabase.service.AuthorizationService;
@Component
public class HibernateDatabaseTest {
public static void main(String[] args) {
@SuppressWarnings("resource")
ApplicationContext context = new ClassPathXmlApplicationContext(
"/spring-context.xml");
HibernateDatabaseTest p = context.getBean(HibernateDatabaseTest.class);
Authorization authorization = new Authorization("000091095650", "1340",
"001", "2012-01-06T09:30:47Z", "MOTO", "4417122900000002",
false, 12, 12, "382", "100", null, null, null, "33606", "USA",
"12345678901234567", "USD", 1540, "5",
"Q0JLSkIyODlWMVBaTDRURFhYV0Y=", "Q0JLSkIyODlWMVBaTDRURFhYV0Y=");
p.start(authorization);
}
@Autowired
private AuthorizationService authorizationService;
private void start(Authorization authorization) {
authorizationService.createAuthorization(authorization);
List<Authorization> list = authorizationService.getAllAuthorizations();
for (Authorization authorizations : list) {
System.out.println(authorizations.getClientId());
}
}
}
When I add em.flush in the GenericDaoImpl class right after the persist, it gives following exception
当我在持久化之后立即在 GenericDaoImpl 类中添加 em.flush 时,它给出以下异常
Exception in thread "main" javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.checkTransactionNeeded(AbstractEntityManagerImpl.java:1171)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1332)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:366)
at com.sun.proxy.$Proxy24.flush(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:241)
at com.sun.proxy.$Proxy20.flush(Unknown Source)
at be.greg.PaymentDatabase.DAO.GenericDaoImpl.create(GenericDaoImpl.java:50)
at be.greg.PaymentDatabase.service.AuthorizationService.createAuthorization(AuthorizationService.java:35)
at be.greg.PaymentDatabase.Tests.HibernateDatabaseTest.start(HibernateDatabaseTest.java:36)
at be.greg.PaymentDatabase.Tests.HibernateDatabaseTest.main(HibernateDatabaseTest.java:27)
So I assume it has to do something with the transaction or perhaps the fact that one hasn't been made. But I have not found the cause for this problem yet
所以我认为它必须对交易做一些事情,或者可能是因为没有进行交易。但是我还没有找到这个问题的原因
Thanks in advance!
提前致谢!
Edit
编辑
These are the dependencies for Spring and Hibernate that I use
这些是我使用的 Spring 和 Hibernate 的依赖项
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.8.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.4.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.29</version>
</dependency>
采纳答案by SergeyB
Try replacing import javax.transaction.Transactional;
with import org.springframework.transaction.annotation.Transactional;
尝试替换import javax.transaction.Transactional;
为import org.springframework.transaction.annotation.Transactional;
回答by Alex Kartishev
Before persisting and merging objects you should open the transaction and then commit it.
在持久化和合并对象之前,您应该打开事务然后提交它。
em.getTransaction.begin();
em.persist(obj);
em.getTransaction().commit();