entitymanager persist不保存到数据库

时间:2014-03-26 14:50:38

标签: java spring hibernate jpa entitymanager

我尝试使用实体管理器中的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>

3 个答案:

答案 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给出的答案。