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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 17:10:56  来源:igfitidea点击:

entitymanager persist does not save to database

javaspringhibernatejpaentitymanager

提问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();

回答by Zeus

I'm thinking that if you have to use the spring transctional, configure the entity manager in the spring itself like linkthis.

我在想,如果您必须使用 spring transctional,请在 spring 本身中配置实体管理器,例如链接这个。

Or you have to use manual transaction management like the Answer given by Alex.

或者您必须使用手动事务管理,如 Alex 给出的答案。