简体   繁体   English

Hibernate 5事务在Spring 4之前尚未启动

[英]Hibernate 5 Transaction not started by Spring 4

Based on this tutorial , I was trying to manage Hibernate 5 transactions with Spring 4. It seems that the transaction has not been started when session.get() method is reached. 根据本教程 ,我尝试使用Spring 4管理Hibernate 5事务。当到达session.get()方法时,似乎尚未启动事务。 How does Spring knows when to start and end a transaction? Spring如何知道何时开始和结束事务? Shouldn't the @Transactional annotation do precisely this? @Transactional注释不应该这样做吗?

Entity 实体

package coproject.cpweb.utils.db.entities;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

import coproject.cpweb.utils.db.entities.Project;
import coproject.cpweb.utils.db.entities.User;

@Entity
@Table( name = "users" )
public class Cbtion {

    @Id
    @GeneratedValue(generator="increment")
    @GenericGenerator(name="increment", strategy = "increment")
    private Integer id;

    @ManyToOne
    private Project project;

    @ManyToOne
    private User creator;

    private Date creationDate;
    private String title;
    private String description;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Project getProject() {
        return project;
    }
    public void setProject(Project project) {
        this.project = project;
    }
    public User getCreator() {
        return creator;
    }
    public void setCreator(User creator) {
        this.creator = creator;
    }
    public Date getCreationDate() {
        return creationDate;
    }
    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}

DAO

package coproject.cpweb.utils.db.daos;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import coproject.cpweb.utils.db.entities.User;

@Service
public class CbtionDAO {

    @Autowired
    SessionFactory sessionFactory;

    public void saveUser(User user) {

        Session session = sessionFactory.getCurrentSession();
        User user_indb = session.get(User.class,user.getId());
        if(user_indb == null) {
            session.save(user);
        }
        else {
            user = user_indb;
        }
    }

    public User getUser(Integer id) {

        Session session = sessionFactory.getCurrentSession();
        User user = session.get(User.class,id);
        return user;
    }

}

Service 服务

package coproject.cpweb.utils.db.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import coproject.cpweb.utils.DbServicesIf;
import coproject.cpweb.utils.db.daos.CbtionDAO;
import coproject.cpweb.utils.db.entities.User;

@Service
public class DbServicesImp implements DbServicesIf{

    @Autowired
    private CbtionDAO cbtionDAO;

    @Transactional
    public void saveUser(User user) {
        cbtionDAO.saveUser(user);
    }

    @Transactional
    public User getUser(Integer id) {
        return cbtionDAO.getUser(id);
    }
}

context beans.xml 上下文bean.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:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd" >

    <tx:annotation-driven />

    <context:component-scan base-package="coproject.cpweb.utils.db.entities" />
    <context:component-scan base-package="coproject.cpweb.utils.db.daos" />
    <context:component-scan base-package="coproject.cpweb.utils.db.services" />

    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
       <property name="driverClassName" value="com.mysql.jdbc.Driver" />
       <property name="url" value="jdbc:mysql://localhost:3306/test" />
       <property name="username" value="jaof" />
       <property name="password" value="iris" />
    </bean>

    <bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource"/>
        <property name="packagesToScan">
            <list>
                <value>coproject.cpweb.utils.db.entities</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.current_session_context_class">thread</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager" >
        <property name="sessionFactory" ref="mySessionFactory" />
    </bean>

</beans>

Main 主要

package coproject.cploc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import coproject.cpweb.utils.db.entities.User;
import coproject.cpweb.utils.db.services.DbServicesImp;

public class FillRandomDb {

public static void main(String[] args) throws Exception {
    @SuppressWarnings("resource")
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

    // TEST String[] bean_names = context.getBeanDefinitionNames();

       DbServicesImp dbServices = (DbServicesImp) context.getBean("dbServicesImp");

       User user = new User();
       user.setUsername("johndoe");
       user.setFirstname("John");
       user.setLastname("Doe");

       dbServices.saveUser(user);

       User user_ret = dbServices.getUser(user.getId());

       System.out.println(user_ret.getFirstname());

}

}

Stack

nov 29, 2015 1:45:37 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@506e6d5e: startup date [Sun Nov 29 13:45:37 CE
T 2015]; root of context hierarchy
nov 29, 2015 1:45:37 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [beans.xml]
nov 29, 2015 1:45:38 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
nov 29, 2015 1:45:38 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.0.2.Final}
nov 29, 2015 1:45:38 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
nov 29, 2015 1:45:38 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
nov 29, 2015 1:45:38 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.0.0.Final}
nov 29, 2015 1:45:39 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
nov 29, 2015 1:45:45 PM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000227: Running hbm2ddl schema export
nov 29, 2015 1:45:46 PM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000230: Schema export complete
nov 29, 2015 1:45:46 PM org.springframework.orm.hibernate5.HibernateTransactionManager afterPropertiesSet
INFO: Using DataSource [org.apache.commons.dbcp.BasicDataSource@5e1d03d7] of Hibernate SessionFactory for HibernateTransactionMana
ger
Exception in thread "main" org.hibernate.HibernateException: get is not valid without active transaction
    at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:33
4)
    at com.sun.proxy.$Proxy23.get(Unknown Source)
    at coproject.cpweb.utils.db.daos.CbtionDAO.saveUser(CbtionDAO.java:19)
    at coproject.cpweb.utils.db.services.DbServicesImp.saveUser(DbServicesImp.java:20)
    at coproject.cpweb.utils.db.services.DbServicesImp$$FastClassBySpringCGLIB$$cd649fcb.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281
)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
    at coproject.cpweb.utils.db.services.DbServicesImp$$EnhancerBySpringCGLIB$$75288f15.saveUser(<generated>)
    at coproject.cploc.FillRandomDb.main(FillRandomDb.java:24)

DAO类应标注为@Repository。

Try to change this line in your file context beans.xml : 尝试在文件上下文beans.xml中更改此行:

  <prop key="hibernate.current_session_context_class">thread</prop>

With this line: 用这行:

 <prop key="current_session_context_class">thread</prop >

And for annotation support, in your spring config bean, add this: 为了获得注释支持,请在您的spring config bean中添加以下内容:

<tx:annotation-driven transaction-manager="transactionManager" mode="proxy" proxy-target-class="true" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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