简体   繁体   中英

entitymanager persist does not save to database

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

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);
    }



}

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

<?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>

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

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

    <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>

Before persisting and merging objects you should open the transaction and then commit it.

em.getTransaction.begin();
em.persist(obj);
em.getTransaction().commit();

Try replacing import javax.transaction.Transactional; with import org.springframework.transaction.annotation.Transactional;

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM