简体   繁体   English

冬眠,春季-交易

[英]hibernate, spring - transaction

I have a project in Spring, where I have 2 connections to the database. 我在Spring中有一个项目,其中有2个与数据库的连接。 Two because one is for read-only connections and the other is for read-write connections. 两个是因为一个用于只读连接,另一个用于读写连接。

My problem is, when I try to invoke method to read only, I get: 我的问题是,当我尝试调用只读方法时,我得到了:

No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

Now I don't know, how to exactly configure my connections. 现在我不知道如何精确配置我的连接。

Below I've inserted my SERVICE CLASS file. 在下面,我插入了我的SERVICE CLASS文件。 The problem is when I'm trying to invoke method with sessionFactoryr , when I'm using sessionFactory - everything is OK. 问题是当我尝试使用sessionFactoryr调用方法时,当我使用sessionFactory -一切正常。

My configuration is: 我的配置是:

hibernate-context.xml: hibernate-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:p="http://www.springframework.org/schema/p" 
            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-3.0.xsd
                http://www.springframework.org/schema/tx 
                http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-3.0.xsd
                ">

        <context:property-placeholder location="/WEB-INF/spring.properties" />

        <!-- Enable annotation style of managing transactions -->
        <tx:annotation-driven transaction-manager="transactionManager" />   
        <tx:annotation-driven transaction-manager="transactionManagerr" />  

        <!-- Declare the Hibernate SessionFactory for retrieving Hibernate sessions -->
        <!-- See http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/orm/hibernate3/annotation/AnnotationSessionFactoryBean.html -->                           
        <!-- See http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/SessionFactory.html -->
        <!-- See http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/Session.html -->

<!-- First Connection -->

        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
                     p:dataSource-ref="dataSource"
                     p:configLocation="${hibernate.config}"
                     p:packagesToScan="com.esb.scs"/>

        <!-- Declare a datasource that has pooling capabilities-->   
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
                    destroy-method="close"
                    p:driverClass="${app.jdbc.driverClassName}"
                    p:jdbcUrl="${app.jdbc.url}"
                    p:user="${app.jdbc.username}"
                    p:password="${app.jdbc.password}"
                    p:acquireIncrement="5"
                    p:idleConnectionTestPeriod="60"
                    p:maxPoolSize="100"
                    p:maxStatements="50"
                    p:minPoolSize="10" />

        <!-- Declare a transaction manager-->
        <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" 
                    p:sessionFactory-ref="sessionFactory" />

<!-- Second connection (read only)  -->                     

        <bean id="sessionFactoryr" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
                     p:dataSource-ref="dataSourcer"
                     p:configLocation="${hibernate.config}"
                     p:packagesToScan="com.esb.scs"/>

        <!-- Declare a datasource that has pooling capabilities-->   
        <bean id="dataSourcer" class="com.mchange.v2.c3p0.ComboPooledDataSource"
                    destroy-method="close"
                    p:driverClass="${app.jdbc.driverClassName}"
                    p:jdbcUrl="${app.jdbc.url}"
                    p:user="${appr.jdbc.username}"
                    p:password="${appr.jdbc.password}"
                    p:acquireIncrement="5"
                    p:idleConnectionTestPeriod="60"
                    p:maxPoolSize="100"
                    p:maxStatements="50"
                    p:minPoolSize="10" />

        <!-- Declare a transaction manager-->
        <bean id="transactionManagerr" class="org.springframework.orm.hibernate3.HibernateTransactionManager" 
                    p:sessionFactory-ref="sessionFactoryr" />



    </beans>

Service Class: 服务等级:

    package com.esb.scs.service;


import static java.lang.System.out;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.esb.scs.domain.User;
import com.esb.scs.domain.UserReference;

@Service("userService")
@Transactional
public class UserService {

    protected static Logger logger = Logger.getLogger("service");

//  @Resource(name="sessionFactoryr")
//  private SessionFactory sessionFactoryr;

    @Resource(name="sessionFactory")
    private SessionFactory sessionFactory;

    @Resource(name="sessionFactoryr")
    private SessionFactory sessionFactoryr;


    public void addUser(HttpServletRequest request){

        logger.info("test");

        Session session = sessionFactory.getCurrentSession();

        PasswordEncoder encoder = new Md5PasswordEncoder();
        String hashedPassword = encoder.encodePassword(request.getParameter("password"), null);

        String login = request.getParameter("login");
        String password = hashedPassword;
        //String role = request.getParameter("role");
        String role = "normal";
        String ip = request.getParameter("ip");
        int active = 1;

        String referenceAddress = request.getParameter("referer");
        String sex = request.getParameter("sex");
        int age = Integer.parseInt(request.getParameter("age"));
        String country = request.getParameter("country");
        String city = request.getParameter("city");
        String education = request.getParameter("education");
        String profession = request.getParameter("profession");
        String branch = request.getParameter("branch");


        Transaction transaction = session.beginTransaction();

        User user = new User();

        UserReference userReference = new UserReference();

        Date dateCreate = new Date();

        user.setEmail(login);
        user.setPassword(password);
        user.setRole(role);
        user.setIp(ip);
        user.setDateCreate(dateCreate);
        user.setLastLoginDate(dateCreate);
        user.setActive(active);
        user.setToken("");

        userReference.setReferenceAddress(referenceAddress);
        userReference.setSex(sex);
        userReference.setAge(age);
        userReference.setCountry(country);
        userReference.setCity(city);
        userReference.setEducation(education);
        userReference.setProfession(profession);
        userReference.setBranch(branch);
        userReference.setSite(referenceAddress);
        userReference.setUser(user);



        userReference.setUser(user);
        user.getUserReferences().add(userReference);

        session.save(user);
        session.save(userReference);

        transaction.commit();

    }

    public List<User> getUser(String name, String password){

        Session session = sessionFactoryr.getCurrentSession();

        String sqlQuery = "FROM User WHERE email='"+name+"' AND password = '" +password+ "'" ;

        Query query = session.createQuery(sqlQuery).setMaxResults(1);

        return query.list();

    }


    public void updateUUID(String uuid, String login, String password){

        Session session = sessionFactory.getCurrentSession();

        Transaction transaction = session.beginTransaction();

        String hql = "update User set token = :token where email = :login and password = :password";

        Query query = session.createQuery(hql);

        query.setString("token", uuid);
        query.setString("login", login);
        query.setString("password", password);

        query.executeUpdate();

        transaction.commit();

    }





}

In addition, I have 另外,我有

<filter>
        <filter-name>hibernateFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>hibernateFilter</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>

in my web.xml. 在我的web.xml中。

According to your advice, if I add @Transactional("transactionManagerr") to my methods - it doesn't change anything, I still get the error. 根据您的建议,如果我将@Transactional("transactionManagerr")添加到我的方法中-它没有任何改变,我仍然会收到错误消息。

I think you have to specify transaction manager name in @Transactional (eg @Transactional("transactionManagerr") ) annotation. 我认为您必须在@Transactional (例如@Transactional("transactionManagerr") )注释中指定事务管理器名称。 Read Documentation and Jira 阅读文档Jira

If you are using transactional annotations you do not need to manually create a transaction in your service class. 如果使用事务注释,则无需在服务类中手动创建事务。

You have specifed the class is transactional this means each method will have its own transaction created by spring. 您已经指定了该类是事务性的,这意味着每个方法将由spring创建自己的事务。

You can also specifiy transactional on each method and further specifiy read only as and when required. 您还可以指定每种方法的事务性,并在需要时进一步指定只读。

If you are using two different datasources you also need to specify which transaction manager is to be used. 如果使用两个不同的数据源,则还需要指定要使用的事务管理器。

<bean id="transactionManagerr" class="org.springframework.orm.hibernate3.HibernateTransactionManager"                p:sessionFactory-ref="sessionFactoryr">
    <qualifier value="transactionManagerr"/>            
</bean>

And in yr service class you do this : 在您的服务等级中,您可以这样做:

@Transactional(value = "transactionManagerr")

Also I would think about renaming everything, just appending "r" to everything is not really descriptive. 另外,我会考虑重命名所有内容,只是在所有内容后附加“ r”并不是真正的描述性内容。

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

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