स्प्रिंग हाइबरनेट - वर्तमान थ्रेड के लिए लेनदेन-सिंक्रनाइज़ेशन सत्र प्राप्त नहीं कर सका


106

मैंने स्प्रिंग + हाइबरनेट के साथ एक एप्लिकेशन बनाया, लेकिन मुझे हमेशा यह त्रुटि मिलती है। हाइबरनेट के साथ यह मेरा पहला आवेदन है, मैंने कुछ गाइड पढ़े लेकिन मैं इस समस्या को हल नहीं कर सकता। मैं कहाँ गलत कर रहा हूँ?

यह मेरे आवेदन का कोड है

ott 05, 2014 4:03:06 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
Informazioni: Refreshing   org.springframework.context.support.ClassPathXmlApplicationContext@1eab16b: startup date  [Sun Oct 05 16:03:06 CEST 2014]; root of context hierarchy
ott 05, 2014 4:03:06 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
Informazioni: Loading XML bean definitions from class path resource [springConfig.xml]
ott 05, 2014 4:03:08 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
ott 05, 2014 4:03:08 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.6.Final}
ott 05, 2014 4:03:08 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
ott 05, 2014 4:03:08 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
ott 05, 2014 4:03:09 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
ott 05, 2014 4:03:09 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
ott 05, 2014 4:03:09 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Exception in thread "main" org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
at coreservlets.StudentDAOImpl.create(StudentDAOImpl.java:19)
at coreservlets.MainApp.main(MainApp.java:14)

student.java

package coreservlets;

public class Student {

    private Integer id;
    private String name;
    private Integer age;

    public Integer getId(){return id;}//getId

    public void setId(Integer id){this.id=id;}//setId

    public String getName(){return name;}//getName

    public void setName(String name){this.name=name;}//setName

    public Integer getAge(){return age;}//getAge

    public void setAge(Integer age){this.age=age;}//setAge

}//Student

studentDAO.java

package coreservlets;

import org.hibernate.SessionFactory;

public interface StudentDAO {

    public void setSessionFactory(SessionFactory sessionFactory);

    public void create(String name,Integer age);

}//StudentDAO

StudentDAOImpl.java

package coreservlets;

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

@Repository
public class StudentDAOImpl implements StudentDAO {

    private SessionFactory sessionFactory;

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory){
        this.sessionFactory=sessionFactory;
    }//setSessionFactory

    public void create(String name,Integer age){
        Session session=sessionFactory.getCurrentSession();
        Student student=new Student();
        student.setName(name);
        student.setAge(age);
        session.save(student);
    }//create

}//StudentDAOImpl

MainApp.java

package coreservlets;

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

public class MainApp {

    public static void main(String[] args) {

        ApplicationContext context=new ClassPathXmlApplicationContext("springConfig.xml");

        StudentDAOImpl student=(StudentDAOImpl) context.getBean("studentDAOImpl");

        student.create("Alessandro", new Integer(33));


    }//main

}//MainApp

springConfig.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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">

<context:annotation-config/>

<context:component-scan base-package="coreservlets"/>

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  <property name="url" value="jdbc:mysql://localhost:3306/spring_hibernate"/>
  <property name="username" value="root"/>
  <property name="password" value="password"/>
  <property name="initialSize" value="5"/>
  <property name="maxTotal" value="10"/>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
    <value>
            hibernate.dialect=org.hibernate.dialect.MySQLDialect
    </value>
</property>

</bean>

</beans>

एसक्यूएल

create table student
(
id integer not null auto_increment,
name varchar(20) not null,
age integer not null,
primary key(id)
);

3
क्या आपने अपने DAO मेथड बनाने के लिए एक @ ट्रेंसेक्शनल को जोड़ने की कोशिश की?
जॉन

1
आप एक हाइबरनेटट्रैक्शनमैनेगर घोषित करना और हाइबरनेट ट्रांसेक्शनल का उपयोग करके विधि बनाना भूल गए।
जेबी निज़ेट

@ इताची सही नहीं है, sessionFactory.openSession()लेनदेन अक्षम हो जाएगा। क्योंकि वे एक ही सत्र नहीं हैं। > वर्ग सेवा में वसंत का एनोटेशन @ ट्रेंसेशनल जोड़ें @ पैट्रिकको सही है! इस सवाल को देखें: stackoverflow.com/questions/15620355/… उदाहरण:@Transactional(readOnly = true, propagation = Propagation.REQUIRED, rollbackFor = {java.lang.Exception.class})
nvanpnco

जवाबों:


200

You must सक्षम लेन-देन का समर्थन ( <tx:annotation-driven>या @EnableTransactionManagement) और घोषितtransactionManager और यह माध्यम से काम करना चाहिए SessionFactory

आपको @Transactionalअपने में जोड़ना होगा@Repository

साथ @Transactionalअपने में @Repositoryवसंत अपने भंडार में लेन-देन संबंधी समर्थन लागू करने में सक्षम है।

आपकी Studentकक्षा में @ javax.persistence नहीं है। * एनोटेशन कैसे @Entity, मैं मान रहा हूं कि उस वर्ग के लिए मैपिंग कॉन्फ़िगरेशन XML के माध्यम से परिभाषित किया गया है।


1
कृपया, क्या आप आवेदन का कोड लिख सकते हैं क्योंकि यह काम नहीं करता है। यह हाइबरनेट के साथ मेरा पहला आवेदन है
एलेक्स

3
<Tx: एनोटेशन-चालित> का एनोटेशन समतुल्य है @EnableTransactionManagement
आनंद

5
इसके अलावा, सुनिश्चित करें कि आप
org.springframework.transaction.annotation.Transactional

चीयर्स दोस्त, मुझे विश्वास है कि मैं इस एनोटेशन से चूक गया :)।
बोल्डबैयर

1
मैंने काम करने के लिए लेन-देन करने के लिए घंटों की कोशिश की है और अंत में मैंने <tx: एनोटेशन-चालित> के बजाय @EnableTransactionManagement का उपयोग किया और सब कुछ पूरी तरह से काम करता है। मैं आपको पर्याप्त धन्यवाद नहीं कर सकता
अबू सुलेमान

38

मेरे पास एक ही मुद्दा था, लेकिन एक वर्ग में जो सेवा परत का हिस्सा नहीं था। मेरे मामले में, लेनदेन प्रबंधक को केवल getBean()विधि द्वारा संदर्भ से प्राप्त किया गया था , और वर्ग दृश्य परत से संबंधित था - मेरी परियोजना OpenSessionInViewतकनीक का उपयोग करती है।

sessionFactory.getCurrentSession()लेखक के रूप में विधि, एक ही अपवाद के कारण किया गया है। मेरे लिए समाधान सरल था।

Session session;

try {
    session = sessionFactory.getCurrentSession();
} catch (HibernateException e) {
    session = sessionFactory.openSession();
}

यदि getCurrentSession()विधि विफल हो जाती है, openSession()तो चाल करना चाहिए।


Hibernate3 से Hibernate5 में अपग्रेड करते समय, मुझे SessionFactoryUtils.getSession () से sessionFactory.getCurrentSession () कोड बदलना पड़ा। उस समय एक ही त्रुटि के पार आया था।
user811433

2
यह वास्तव में बुरा व्यवहार देता है कि यदि sessionFactory.getCurrentSession();सफल हो जाता है तो सत्र बंद नहीं होना चाहिए लेकिन यदि sessionFactory.openSession();यह सफल होता है तो इसे बंद कर देना चाहिए
रिचर्ड टिंगल

1
@RichardTingle से सहमत हैं। OpenSession की तरह लगता है अपवाद को बायपास करने के लिए एक हैक है। इसके लिए निष्क्रिय समाधान क्या होना चाहिए?
प्रवीण शेंडगे

@Praveen मैं वास्तव में क्या किया था एक सेवा एक लंबो स्वीकार Function<Session,T>अर्थ था "अगर मैं एक सत्र था मैं इसे एक्स करने के लिए उपयोग करेंगे"। फिर विधि प्रोविजनिंग को हैंडल करती है और (यदि नेकेसीसरी) सत्र को डिप्राइवेट कर रही है, और बस टी लौटाती है। तो सेवा के बाहरी उपभोक्ताओं को वास्तव में एक सत्र में अपने हाथ नहीं मिलते हैं
रिचर्ड टिंगल

इसने बिना किसी त्रुटि के मेरा कार्यक्रम चलाया। मुझे चिंता है कि इस तरह से बनाए गए कई प्रश्नों में मेरा कोई लेन-देन नहीं है, जिसका अर्थ है कि मैं असंगत परिणामों को वापस करने का जोखिम उठाता हूं?
ओले वीवी

13

वर्ग सेवा में एनोटेशन @ ट्रान्सैक्शनल ऑफ स्प्रिंग जोड़ें


3

अपने xyz.DAOImpl.java में

निम्न चरण करें:

// स्टेप -1: सेशन फैक्ट्री सेट करें

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

public void setSessionFactory(SessionFactory sf)
{
    this.sessionFactory = sf;
}

// चरण -2: वर्तमान सत्र प्राप्त करने का प्रयास करें, और हाइबरनेट अपवाद अपवाद को पकड़ें।


// चरण -3: यदि कोई हाइबरनेट अपवाद अपवाद हैं, तो OpenSession प्राप्त करना सही है।

try 
{
    //Step-2: Implementation
    session = sessionFactory.getCurrentSession();
} 
catch (HibernateException e) 
{
    //Step-3: Implementation
    session = sessionFactory.openSession();
}

नमस्ते! क्या हाइबरनेट को खुद से ऐसा नहीं करना चाहिए?
क्रिस

2

मैंने web.xml में इन कॉन्फ़िगरेशन को जोड़ा और यह मेरे लिए अच्छा काम करता है!

<filter>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>sessionFactoryBeanName</param-name>
        <param-value>sessionFactory</param-value>
    </init-param>
    <init-param>
        <param-name>flushMode</param-name>
        <param-value>AUTO</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

इसके अतिरिक्त, पहले स्थान पर घबराहट से आवेदन को रोकने के लिए सबसे अधिक रैंक वाला उत्तर मुझे सुराग देता है।


1
मैं स्प्रिंगएमवीसी 4 और हाइबरनेट 5
'25

2

आपको अपने DAO विधि से लेन-देन की अनुमति देने की आवश्यकता है। जोड़े,

@Transactional(readOnly = true, propagation=Propagation.NOT_SUPPORTED)

अपने दाव तरीकों पर। और @Transactionalपैकेज से होना चाहिए:

org.springframework.transaction.annotation.Transactional

1

मुझे यह त्रुटि इसलिए भी हुई क्योंकि जिस फ़ाइल में मैंने @Transactional एनोटेशन का उपयोग किया था, मैं गलत वर्ग आयात कर रहा था

import javax.transaction.Transactional; 

Javax के बजाय, का उपयोग करें

import org.springframework.transaction.annotation.Transactional; 

1

मेरा समाधान था (स्प्रिंग का उपयोग करके) उस विधि को डालना जो किसी अन्य विधि के अंदर विफल हो जाती है जो लेन-देन करता है और बनाता है।

ऐसा करने के लिए मैंने पहली बार निम्नलिखित इंजेक्शन लगाए:

@Autowired
private PlatformTransactionManager transactionManager;

और आखिरकार ऐसा किया:

public void newMethod() {
    DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
    TransactionStatus transaction = transactionManager.getTransaction(definition);

    oldMethod();

    transactionManager.commit(transaction);
}


0

मेरा विन्यास इस तरह था। मेरे पास एक क्वार्टजजॉब , एक सेवा बीन और डाओ था। हमेशा की तरह इसे LocalSessionFactoryBean (हाइबरनेट के लिए) और क्वार्ट्ज ढांचे के लिए SchedulerFactoryBean के साथ कॉन्फ़िगर किया गया था। क्वार्ट्ज नौकरी लिखते समय, मैंने गलती से इसे @ सेवा के साथ एनोटेट कर दिया था , मुझे ऐसा नहीं करना चाहिए था क्योंकि मैं क्वार्ट्जबैन का उपयोग करने के लिए एक और रणनीति का उपयोग कर रहा था करते हुए वायरिंग

तो वास्तव में क्या हो रहा था कि क्वार्ट्ज ऑटोवीयर के कारण, जॉब बीन को इंजेक्ट किया जा रहा था और उसी समय Tx संदर्भ @ के आधार पर निर्धारित किया गया था सेवा के एनोटेशन के और इसलिए TX सिंक से बाहर गिर रहा था !!

मुझे उम्मीद है कि यह उन लोगों के लिए मदद करेगा जिनके ऊपर समाधान वास्तव में समस्या हल नहीं हुई। मैं स्प्रिंग 4.2.5 और हाइबरनेट 4.0.1 का उपयोग कर रहा था,

मैं देखता हूं कि इस सूत्र में DAO (@ रिपोजिटरी ) में @ ट्रांजेक्शनल एनोटेशन को जोड़ने का एक अनावश्यक सुझाव है , यह एक बेकार सुझाव है क्योंकि @ रिपोजिटरी में वह सब है जिसे विशेष रूप से उस ट्रांजेक्शनल को सेट करने की आवश्यकता नहीं है । DAO, जैसा कि DAO उन सेवाओं से कहा जाता है, जिन्हें पहले से ही @Trasancational द्वारा इंजेक्ट किया जा रहा है । मुझे आशा है कि यह सहायक लोग हो सकते हैं जो क्वार्ट्ज, स्प्रिंग और हाइबरनेट का एक साथ उपयोग कर रहे हैं।


0

वसंत- servlet.xml में transaction-managerअपने को जोड़ें :<annotation-driven/>

<tx:annotation-driven transaction-manager="yourTransactionBeanID"/>

0

अपने दाओ वर्ग की जाँच करें। यह इस तरह होना चाहिए:

Session session = getCurrentSession();
Query query = session.createQuery(GET_ALL);

और एनोटेशन:

@Transactional
@Repository

0

मुझे उसी समस्या का सामना करना पड़ा और आखिरकार पता चला कि जहां घटक-स्कैन तत्व ने एनोटेट वर्ग को सक्षम <tx:annotaion-driven />नहीं किया था , उसके भीतर परिभाषित नहीं किया गया था ।[dispatcher]-servlet.xml@service

बस <tx:annotaion-driven />घटक-स्कैन तत्व के साथ डाल दिया , समस्या गायब हो गई।


0

मेरा समान मुद्दा नीचे 2 दृष्टिकोणों के साथ तय हो गया।

1) मैन्युअल रूप से लेनदेन को संभालने के माध्यम से:

Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
UserInfo user = (UserInfo) session.get(UserInfo.class, 1);
tx.commit();

2) अपने web.xmlफ़िल्टर और उपयोग सुनिश्चित करने के लिए स्प्रिंग को लेनदेन खोलने और प्रबंधित करने के लिए कहें @Repository @Transactional:

<filter>
  <filter-name>hibernateFilter</filter-name>
  <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
  <init-param>
    <param-name>sessionFactory</param-name>
    <param-value>session.factory</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>hibernateFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

0

मैनडियर की टिप्पणी के लिए धन्यवाद। मैं स्प्रिंगमिक्स का उपयोग करता हूं और मेरे मामले में मुझे इसका उपयोग करना है

@Repository
@Transactional
@EnableTransactionManagement
public class UserDao {
...
}

और मैं pom.xml में स्प्रिंग-संदर्भ भी जोड़ता हूं और यह काम करता है


0

मेरी भी यही समस्या थी। मैंने इसे निम्नलिखित करते हुए हल किया:

  1. इस लाइन को dispatcher-servletफाइल में जोड़ें :

    <tx:annotation-driven/>

    <beans>एक ही फ़ाइल में अनुभाग के ऊपर की जाँच करें । ये दो लाइनें मौजूद होनी चाहिए:

    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation= "http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
  2. यह भी सुनिश्चित करें कि आपने जोड़ा है @Repositoryऔर @Transactionalआप कहां उपयोग कर रहे हैं sessionFactory

    @Repository
    @Transactional
    public class ItemDaoImpl implements ItemDao {
        @Autowired
        private SessionFactory sessionFactory;

-1

ऊपर इस वर्ग में @Repositoryसिर्फ एक और एनोटेशन रखा गया है जो @Transactionalकाम करेगा। अगर यह वापस काम करता है ( Y/ N):

@Repository
@Transactional
public class StudentDAOImpl implements StudentDAO

1
एसओ में आपका स्वागत है। कृपया एक अच्छा उत्तर कैसे लिखें ? SO में Y / N का उत्तर देने का कोई रिवाज नहीं है। यदि आपका उत्तर उस व्यक्ति के लिए काम करता है जिसे वे चिन्हित करेंगे, जैसा कि स्वीकृत है। एक उपयोगी उत्तर भी उत्कीर्ण किया जा सकता है।
श्री9911
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.