স্প্রিং হাইবারনেট - বর্তমান থ্রেডের জন্য লেনদেন-সিঙ্ক্রোনাইজড অধিবেশন পাওয়া যায়নি


105

আমি স্প্রিং + হাইবারনেট দিয়ে একটি অ্যাপ্লিকেশন তৈরি করেছি তবে আমি সর্বদা এই ত্রুটিটি পাই। হাইবারনেট সহ এটি আমার প্রথম অ্যাপ্লিকেশন, আমি কয়েকটি গাইড পড়েছি তবে আমি এই সমস্যাটি সমাধান করতে পারি না। আমি কোথায় ভুল করছি?

এটি আমার আবেদনের কোড

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>

SQL

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

3
আপনি কি আপনার ডিএও তৈরির পদ্ধতিতে একটি @ ট্রান্সজেকশনাল যুক্ত করার চেষ্টা করেছিলেন?
জন

1
আপনি একটি হাইবারনেট ট্রান্সজেকশন ম্যানেজার ঘোষণা করতে এবং হাইবারনেট লেনদেন ব্যবহার করে পদ্ধতিটি তৈরি করতে ভুলে গেছেন।
জেবি নিজেট

@ আইটাচি সঠিক নয়, sessionFactory.openSession()লেনদেনটি অক্ষম হবে। কারণ তারা একই অধিবেশন নয়। > ক্লাস সার্ভিসে টীকা যোগ করুন @ বসন্তের লেনদেন @ প্যাট্রিকোকো সঠিক! এই প্রশ্নের দেখুন: stackoverflow.com/questions/15620355/... : উদাহরণস্বরূপ@Transactional(readOnly = true, propagation = Propagation.REQUIRED, rollbackFor = {java.lang.Exception.class})
nvnpnco

উত্তর:


200

আপনাকে অবশ্যই লেনদেন সমর্থন ( বা ) সক্ষম করতে হবে এবং এটি ঘোষণা করতে হবে এবং এটির মাধ্যমে কাজ করা উচিত ।<tx:annotation-driven>@EnableTransactionManagementtransactionManagerSessionFactory

আপনি অবশ্যই @Transactionalআপনার মধ্যে যোগ করা উচিত@Repository

@Transactionalআপনার @Repositoryবসন্ত সহ আপনার ভান্ডারগুলিতে লেনদেনমূলক সহায়তা প্রয়োগ করতে সক্ষম।

তোমার Studentবর্গ কোন @ javax.persistence হয়েছে। * টীকা কিভাবে @Entity, আমি ম্যাপিং কনফিগারেশন অভিমানী করছি যে বর্গ জন্য XML মাধ্যমে সংজ্ঞায়িত করা হয়েছে।


1
দয়া করে, আপনি কি অ্যাপ্লিকেশনটির কোডটি লিখতে পারেন কারণ এটি কাজ করে না..হাইবার্নেটের সাথে এটি আমার প্রথম অ্যাপ্লিকেশন
অ্যালেক্স

3
<Tx: টিকা-চালিত> এর টীকা সমেত হ'ল @ সক্ষম ট্রান্সজেকশন ম্যানেজমেন্ট
আনন্দ রকজ

5
এছাড়াও, নিশ্চিত হয়ে নিন যে আপনি org.springframework.transaction.annotation.Transactional ব্যবহার করেছেন, javax.persistance.Transactional
imnd_neel

চিয়ারস সাথী, আমি বিশ্বাস করতে পারি না আমি এই টিকাটি মিস করেছি :)।
বোলডবায়ার

1
আমি লেনদেনটি কাজ করার জন্য কয়েক ঘন্টা চেষ্টা করেছি এবং শেষ পর্যন্ত আমি <tx: টিকা: চালিত> এর পরিবর্তে @EnableTransactionManagement ব্যবহার করেছি এবং সবকিছু পুরোপুরি কার্যকরভাবে কাজ করে। আমি আপনাকে যথেষ্ট ম্যানুয়েলকে ধন্যবাদ জানাতে পারি না
আবু সুলাইমান

39

আমার একই সমস্যা ছিল, তবে ক্লাসে যা পরিষেবা স্তরের অংশ ছিল না। আমার ক্ষেত্রে, লেনদেন পরিচালকের getBean()পদ্ধতিটি সহজভাবে প্রসঙ্গে থেকে নেওয়া হয়েছিল , এবং শ্রেণিটি ভিউ স্তরের অন্তর্ভুক্ত - আমার প্রকল্পটি OpenSessionInViewপ্রযুক্তি ব্যবহার করে ।

sessionFactory.getCurrentSession()লেখকের যেমন পদ্ধতি, একই ব্যতিক্রম ঘটাচ্ছে হয়েছে। আমার জন্য সমাধানটি বরং সহজ ছিল।

Session session;

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

যদি getCurrentSession()পদ্ধতিটি ব্যর্থ হয় openSession()তবে কৌশলটি করা উচিত।


হাইবারনেট 3 থেকে হাইবারনেট 5 এ আপগ্রেড করার সময়, আমি কোডটি সেশনফ্যাক্টরি ইউটেলস.জেটসেশন () থেকে সেশনে ফ্যাক্টরি.সেটকারেন্টসেশন () এ পরিবর্তন করতে হয়েছিল। সেই সময় একই ত্রুটি জুড়ে এসেছিল।
ব্যবহারকারী 811433

2
এটি সত্যিই বাজে আচরণ দেয় যে যদি sessionFactory.getCurrentSession();সফল হয় তবে অধিবেশনটি বন্ধ করা উচিত নয় তবে sessionFactory.openSession();সফল হলে এটি অবশ্যই বন্ধ করা উচিত
রিচার্ড টিংল

1
@ রিচার্ডটিঙ্গলে সম্মতি দিন মনে হয় ওপেনসেশন ব্যতিক্রমটি বাইপাস করার জন্য একটি হ্যাক। এর অলস সমাধানটি কী হওয়া উচিত?
প্রবীণ শেন্ডেজ

@ প্রবীণ আমি আসলে যা করেছি তা হ'ল একটি পরিষেবা একটি ল্যাম্বডা গ্রহণ করার Function<Session,T>অর্থ ছিল "যদি আমার একটি সেশন হয় তবে আমি এক্স করতে এটি ব্যবহার করতাম"। তারপর পদ্ধতি হ্যান্ডলগুলি প্রভিশনিং এবং (neccissary তাহলে) অধিবেশন প্রস্তুতি ত্যাগ, এবং শুধুমাত্র টি ফেরৎ সুতরাং সেবা বাইরের ক্রেতাদের আসলে একটি সেশন তাদের হাত পেতে
রিচার্ড শিহরিয়া

এটি আমার প্রোগ্রামটিকে ত্রুটির চিহ্ন ছাড়াই চালিত করে। আমি উদ্বিগ্ন যে এইভাবে তৈরি করা একাধিক প্রশ্নের জুড়ে আমার কোনও লেনদেন নেই, যার অর্থ আমি বেমানান ফলাফলগুলি ফেরাতে ঝুঁকিপূর্ণ?
ওলে ভিভি

13

ক্লাস পরিষেবাতে টীকা @ ট্রান্সএশনাল অফ স্প্রিং যুক্ত করুন


3

আপনার xyz.DAOImpl.java তে

নিম্নলিখিত পদক্ষেপগুলি করুন:

// পদক্ষেপ -১: সেশন কারখানা সেট করুন

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

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

// পদক্ষেপ -২: বর্তমান সেশনটি পাওয়ার চেষ্টা করুন এবং হাইবারনেট এক্সেপশন ব্যতিক্রমটি ধরুন catch


// পদক্ষেপ -3: যদি কোনও হাইবারনেট এক্সসেপশন ব্যতিক্রম হয় তবে ওপেনসেশন পাওয়ার জন্য সত্য।

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

ওহে! হাইবারনেট নিজে থেকে এটি করার কথা নয়?
ক্রিস

2

আমি এই কনফিগারেশনগুলিকে ওয়েব.এক্সএমএল এ যুক্ত করেছি এবং এটি আমার পক্ষে ভাল কাজ করে!

<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
আমি springMVC 4 এবং হাইবারনেট 5 ব্যবহার করছি
何德福

2

আপনার ডিএও পদ্ধতিতে আপনার লেনদেনের অনুমতি দেওয়া দরকার। যোগ করুন,

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

আপনার দাও পদ্ধতিতে এবং @Transactionalপ্যাকেজ থেকে হওয়া উচিত:

org.springframework.transaction.annotation.Transactional

1

আমার এই ত্রুটিটিও ছিল কারণ আমি যে ফাইলটিতে @Transactional টিকা ব্যবহার করেছিলাম সেখানে ভুল শ্রেণি আমদানি করছিলাম

import javax.transaction.Transactional; 

জাভ্যাক্সের পরিবর্তে, ব্যবহার করুন

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

আমার কনফিগারেশনটি এরকম ছিল। আমার একটি কোয়ার্টজবব , একটি পরিষেবা বিন এবং দাও ছিল। যথারীতি এটি লোকালসেশনফ্যাক্টরিবিয়ান (হাইবারনেটের জন্য), এবং কোয়ার্টজ ফ্রেমওয়ার্কের জন্য শিডিয়ুলফ্যাক্টরিবিয়ান দ্বারা কনফিগার করা হয়েছিল। যখন কোয়ার্টজ কাজ লেখা, আমি ভুল করে এটা দিয়ে @ সটীক পরিষেবা , আমি যে কারণ আমি অন্য কৌশল ব্যবহার করছিলেন টেলিগ্রাম না কাজ করা উচিত QuartzBean ব্যবহার AutowiringSpringBeanJobFactory ব্যাপ্ত SpringBeanJobFactory

সুতরাং আসলে যা ঘটছিল তা হ'ল কোয়ার্টজ অটোয়ারের কারণে টিএক্স জোব বিনের সাথে ইনজেকশনের শিকার হচ্ছিল এবং একই সময়ে টিএক্স কনটেক্সটটি @ সার্ভিস টিকাশনের কারণে সেট করা হয়েছিল এবং তাই টিএক্স সিঙ্কের বাইরে চলে যাচ্ছিল !!

আমি আশা করি এটি যাদের জন্য উপরোক্ত সমাধানগুলি সত্যই সমস্যাটি সমাধান করেনি তাদেরকে সহায়তা করবে। আমি স্প্রিং 4.2.5 এবং হাইবারনেট ৪.০.১ ব্যবহার করছিলাম,

আমি দেখতে এই থ্রেড @ যোগ করার জন্য একটি অপ্রয়োজনীয় পরামর্শ নেই লেনদেনগত দাও (@ জন্য টীকা সংগ্রহস্থলের প্রয়োগ ), একটি অনর্থক পরামর্শ কারণ @ যে সংগ্রহস্থলের প্রয়োগ হয়েছে সব প্রয়োজন আছে কি বিশেষভাবে সেট করতে হবে না @ লেনদেনের উপর ডিএওগুলি, যেমন ডিএওগুলিকে সেবার থেকে কল করা হয়েছে যা ইতিমধ্যে @ ট্রান্সানকেশনাল দ্বারা ইনজেকশন করা হয়েছে । আমি আশা করি, এটি কোয়ার্টজ, স্প্রিং এবং হাইবারনেট একসাথে ব্যবহার করে এমন লোকদের পক্ষে সহায়ক হতে পারে।


0

যোগ transaction-managerআপনার টু <annotation-driven/>মধ্যে বসন্ত-servlet.xml:

<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 পদ্ধতির সাথে স্থির হয়ে গেছে fixed

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
তাই আপনাকে স্বাগতম। কল্যাণকামী মধ্য দিয়ে যেতে আমি কিভাবে ভাল উত্তর লিখতে না । এসওতে ওয়াই / এন উত্তর দেওয়ার কোনও প্রথা নেই। আপনার উত্তর যদি সেই ব্যক্তির পক্ষে কাজ করে তবে তারা চিহ্নিত করবে accepted একটি সহায়ক উত্তরও upvated হতে পারে।
শ্রী 9911 6
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.