我尝试使用实体管理器中的persist方法保存到我的数据库时遇到问题。执行它时,它不会产生异常,但它不会将对象保存到我的数据库中。读取手动插入的对象确实有效。
GenericDAOImpl
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
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);
}
}
授权
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 ...
弹簧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 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中
<?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>
可运行的主要类
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());
}
}
}
当我在持久化之后立即在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)
所以我认为它必须对交易做一些事情,或者也许事实上还没有做出。但我还没有找到导致这个问题的原因
提前致谢!
修改的
这些是我使用的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>
答案 0 :(得分:4)
在持久化和合并对象之前,您应该打开事务然后提交它。
em.getTransaction.begin();
em.persist(obj);
em.getTransaction().commit();
答案 1 :(得分:4)
尝试将import javax.transaction.Transactional;
替换为import org.springframework.transaction.annotation.Transactional;
答案 2 :(得分:0)
我认为如果你必须使用spring transctional,请在spring中配置实体管理器,如link这个。
或者您必须使用手动事务管理,如Alex给出的答案。