session.connection () हाइबरनेट पर पदावनत?


80

हमें java.sql.Connectionहाइबरनेट सत्र से संबंधित होने में सक्षम होना चाहिए । कोई अन्य कनेक्शन काम नहीं करेगा, क्योंकि यह कनेक्शन चल रहे लेनदेन से जुड़ा हो सकता है।

यदि session.connection () अब पदावनत हो गया है, तो मुझे यह कैसे करना चाहिए?


यदि कोई इसके बारे में अधिक पढ़ना चाहता है: hibernate.onjira.com/browse/HHH-2603
WW।

9
हाइबरनेट नामक इस भयानक ढांचे से दूर रहने के कई कारणों में से एक है। जैसा कि नाम से ही स्पष्ट है कि यह हमेशा के लिए सो जाता है।
क्रिसपोटेक

2
@chrisapotek आपको हाइबरनेट पसंद नहीं है ... क्या आपके पास कोई विकल्प है या आप हाथ से सभी दृढ़ता सामान लिखते हैं?
एमबोरसा

1
कैसे mybatis के बारे में?
ज्योफ्री रिचेची

जवाबों:


86

अब आपको वर्क एपीआई का उपयोग करना होगा:

session.doWork(
    new Work() {
        public void execute(Connection connection) throws SQLException 
        { 
            doSomething(connection); 
        }
    }
);

या, जावा 8+ में:

session.doWork(connection -> doSomething(connection)); 

1
मुझे पदावनत सामान का उपयोग करना पसंद नहीं है, लेकिन मुझे लगता है कि इसका उपयोग शुरू करने का यह एक अच्छा कारण है। लेकिन मुझे वर्क एपीआई के बारे में नहीं पता था। बहुत बहुत धन्यवाद।
ट्रेडजॉइचैगो

1
वाह। मैं हाइबरनेट 3.2.7.ga का उपयोग कर रहा हूं, लेकिन मेरे org.hibernate.Session में कोई doWork विधि नहीं है। एक दम बढ़िया!
ट्रेडरजियोचैगो

25
वह बदसूरत है। लोगों को हमेशा किसी चीज के लिए कच्चे कनेक्शन की आवश्यकता होती है - उन्हें इसे आसान बनाना चाहिए।
पीटर

9
SessionImpl sessionImpl = (SessionImpl) session; Connection conn = sessionImpl.connection();आप तब कनेक्शन ऑब्जेक्ट का उपयोग कहीं भी कर सकते हैं, जिसकी आपको उस कोड में आवश्यकता होती है, न कि केवल एक छोटी विधि तक सीमित।
साइमन एमबीटिया

2
Java8 में और भी कम - session.doWork(this::doSomething)। यदि आप एक परिणाम वापस करना चाहते हैं - doReturningWork ()
Optio

22

यदि session.connect()अब पदावनत कर दिया जाता है, तो मुझे यह कैसे करना चाहिए?

आपको जावाडॉक में उल्लिखित एपीआई Session#doWork(Work)और Workएपीआई का उपयोग करना होगा :

connection()
     पदावनत किया हुआ। (4.x में हटाने के लिए निर्धारित)। प्रतिस्थापन आवश्यकता पर निर्भर करता है; प्रत्यक्ष JDBC सामान उपयोग करने के लिए doWork(org.hibernate.jdbc.Work); 'अस्थायी सत्र' का उपयोग (टीबीडी) खोलने के लिए।

आपके पास Hibernate 4.x से पहले कुछ समय है, लेकिन, अच्छी तरह से, एक अपग्रेड किए गए एपीआई का उपयोग करके किसी तरह इस तरह दिखता है:

वैकल्पिक शब्द:)

अपडेट: आरई के अनुसार : [हाइबरनेट-देव] हाइबरनेट-देव सूची में शामिल होने वाला कनेक्शन , ऐसा लगता है कि डिप्रैशन का प्रारंभिक उद्देश्य उपयोग को हतोत्साहित Session#connection()करना था क्योंकि इसे "खराब" एपीआई माना जाता था, लेकिन यह उस समय रहना था। मुझे लगता है कि उन्होंने अपना मन बदल दिया ...


2
यहां मेरा जावेदोक आपसे थोड़ा अलग है। बस थोड़ा कम स्पष्ट: कनेक्शन के खिलाफ काम करने के लिए एक एसपीआई के साथ प्रतिस्थापित किया जाना; 4.x में हटाने के लिए निर्धारित। आपका JavaDoc यह सब कहता है। यह जावाडॉक कुछ नहीं कहता है।
ट्रेडजॉइचैगो

@ शेरगियो वास्तव में। लेकिन अगर मैं कर सकता हूं, तो आपको अपने प्रश्न में हाइबरनेट संस्करण जैसी महत्वपूर्ण चीजों का उल्लेख करना चाहिए। आपका संस्करण बहुत पुराना है ( Session#connection()हाइबरनेट कोर 3.3 में javadoc विकल्प का उल्लेख है) और यह आमतौर पर कुछ पाठकों का अनुमान नहीं लगा सकता है।
पास्कल थिवेंट

@ पास्कल संस्करण 3.2.7.ga नवीनतम है जो मैं मावेन पर पा सकता हूं। GroupId = org.hibernate और विरूपण साक्ष्य = hibernate। मुझे आश्चर्य है कि क्या मावेन नवीनतम संस्करण प्रदान कर सकता है या यदि आपको केवल जार की प्रतिलिपि बनाने और मावेन को अनदेखा करने की आवश्यकता है।
ट्रेडरज्योइकोगो

@Sergio ऐसा इसलिए है क्योंकि आप पुराने अखंड जार ( hibernate) का उपयोग कर रहे हैं और न hibernate-coreकि जिसके हाल के संस्करण हैं। और अंतिम संस्करणों (3.5.x) के लिए, वे JBoss Nexus रिपॉजिटरी में उपलब्ध हैं ।
पास्कल थिवेंट

1
@ पास्कल धन्यवाद! एक बड़ी समस्या यह है कि मुझे कनेक्शन पास करने की आवश्यकता है, इसलिए यदि हाइबरनेट मुझे इसके कनेक्शन के साथ प्रदान करने में सक्षम नहीं होगा, तो यह खराब होगा। मुझे यह कनेक्शन किसी और तरह से प्राप्त करने की आवश्यकता होगी। मुझे लगता है कि जिस किसी को भी कनेक्शन विधि को हटाने का यह विचार था उसे फिर से सोचना चाहिए।
TraderJoeChicago

12

इसे इस्तेमाल करे

((SessionImpl)getSession()).connection()

Actuly getSession रिटर्न सत्र इंटरफ़ेस प्रकार, आपको यह देखना चाहिए कि सत्र के लिए मूल वर्ग क्या है, मूल वर्ग पर टाइप करें फिर कनेक्शन प्राप्त करें।

सौभाग्य!


1
❤️ uuuuu इतना निराशाजनक है कि यह आवश्यक है - मेरे ऐप सेटअप प्राप्त करने की कोशिश कर रहा है ताकि रीड रेप्लिका को वितरित करने के लिए आसानी से कनेक्शन स्थापित किया जा सके। धन्यवाद।
सैम बेरी

1
यह अधिक upvotes क्यों नहीं है? क्या ऐसा कुछ कारण है जो नहीं किया जाना चाहिए? मेरे लिए पूरी तरह से काम करता है।

@ टिल्पर SessionImplहाइबरनेट के एक आंतरिक पैकेज में है (इसलिए इसका उपयोग करने का इरादा नहीं है) और यह भी कि वास्तविक कार्यान्वयन पर निर्भरता है। इसके अलावा, आप अपने परीक्षणों में सत्र को आसानी से नहीं रोक सकते, जब आप इसे डालते हैं।
विक

9

अभी भी बहुत सारे कलाकारों के साथ एक और विकल्प शामिल है, लेकिन कम से कम इसे प्रतिबिंब की आवश्यकता नहीं है, जो आपको वापस संकलन का समय देगा:

public Connection getConnection(final EntityManager em) {
  HibernateEntityManager hem = (HibernateEntityManager) em;
  SessionImplementor sim = (SessionImplementor) hem.getSession();
  return sim.connection();
}

आप निश्चित रूप से कुछ instanceofचेक के साथ "प्रेटियर" भी बना सकते हैं , लेकिन ऊपर दिया गया संस्करण मेरे लिए काम करता है।


9

यहाँ यह हाइबरनेट 4.3 में करने का एक तरीका है, और इसे पदावनत नहीं किया गया है:

  Session session = entityManager.unwrap(Session.class);
  SessionImplementor sessionImplementor = (SessionImplementor) session;
  Connection conn = sessionImplementor.getJdbcConnectionAccess().obtainConnection();

1
क्या इसे रूपांतरित sessionकरना सुरक्षित है SessionImplementor?
मेसर्स

@DerekY, मुझे पता है कि यह पुराना है, लेकिन अभी इससे निपटना है। और हाँ, यह है। सभी सत्र कार्यान्वयन भी किसी तरह से सत्र कार्यान्वयनकर्ता हैं।
रेजिनाल्डो सैंटोस

9

यह वही है जो मैं उपयोग करता हूं और मेरे लिए काम करता हूं। सत्र ऑब्जेक्ट को एक सत्र I में डुबोएं और कनेक्शन ऑब्जेक्ट को आसानी से प्राप्त करें:

SessionImpl sessionImpl = (SessionImpl) session;
Connection conn = sessionImpl.connection();

sessionआपके हाइबरनेट सत्र ऑब्जेक्ट का नाम कहां है।


8

connection()बस इंटरफ़ेस पर पदावनत किया गया था। यह अभी भी उपलब्ध हैSessionImpl । आप वह कर सकते हैं जो स्प्रिंग करता है और बस उसी को कॉल करें।

यहाँ HibernateJpaDialectस्प्रिंग 3.1.1 से कोड है

public Connection getConnection() {
        try {
            if (connectionMethod == null) {
                // reflective lookup to bridge between Hibernate 3.x and 4.x
                connectionMethod = this.session.getClass().getMethod("connection");
            }
            return (Connection) ReflectionUtils.invokeMethod(connectionMethod, this.session);
        }
        catch (NoSuchMethodException ex) {
            throw new IllegalStateException("Cannot find connection() method on Hibernate session", ex);
        }
    }

15
इस तरह की चीजें हैं जो भयानक हाइबरनेट आपको बनाती हैं। कुछ रूपरेखा हाइबरनेट के रूप में बहुत खराब हैं।
च्रिसपोटेक

8

मुझे यह लेख मिला

package com.varasofttech.client;

import java.sql.Connection;
import java.sql.SQLException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.SessionImpl;
import org.hibernate.jdbc.ReturningWork;
import org.hibernate.jdbc.Work;

import com.varasofttech.util.HibernateUtil;

public class Application {

public static void main(String[] args) {

    // Different ways to get the Connection object using Session

    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    Session session = sessionFactory.openSession();

    // Way1 - using doWork method
    session.doWork(new Work() {
        @Override
        public void execute(Connection connection) throws SQLException {
            // do your work using connection
        }

    });

    // Way2 - using doReturningWork method
    Connection connection = session.doReturningWork(new ReturningWork<Connection>() {
        @Override
        public Connection execute(Connection conn) throws SQLException {
            return conn;
        }
    });

    // Way3 - using Session Impl
    SessionImpl sessionImpl = (SessionImpl) session;
    connection = sessionImpl.connection();
    // do your work using connection

    // Way4 - using connection provider
    SessionFactoryImplementor sessionFactoryImplementation = (SessionFactoryImplementor) session.getSessionFactory();
    ConnectionProvider connectionProvider = sessionFactoryImplementation.getConnectionProvider();
    try {
        connection = connectionProvider.getConnection();
        // do your work using connection
    } catch (SQLException e) {
        e.printStackTrace();
    }
}
}

इसने मेरी मदद की।


6

साथ Hibernate> = 5.0 आप प्राप्त कर सकते हैं Connectionइस तरह:

Connection c = sessionFactory.
getSessionFactoryOptions().getServiceRegistry().
getService(ConnectionProvider.class).getConnection();

3

Hibenate 4.3 के लिए यह प्रयास करें:

public static Connection getConnection() {
        EntityManager em = <code to create em>;
        Session ses = (Session) em.getDelegate();
        SessionFactoryImpl sessionFactory = (SessionFactoryImpl) ses.getSessionFactory();
        try{
            connection = sessionFactory.getConnectionProvider().getConnection();
        }catch(SQLException e){
            ErrorMsgDialog.getInstance().setException(e);
        }
        return connection;
    }

1

इसे इस्तेमाल करे:

public Connection getJavaSqlConnectionFromHibernateSession() {

    Session session = this.getSession();
    SessionFactoryImplementor sessionFactoryImplementor = null;
    ConnectionProvider connectionProvider = null;
    java.sql.Connection connection = null;
    try {
        sessionFactoryImplementor = (SessionFactoryImplementor) session.getSessionFactory();
        connectionProvider = (ConnectionProvider) sessionFactoryImplementor.getConnectionProvider().getConnection();
        connection = connectionProvider.getConnection();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return connection;
}

0
    Connection conn = null;
    PreparedStatement preparedStatement = null;
    try {
        Session session = (org.hibernate.Session) em.getDelegate();
        SessionFactoryImplementor sfi = (SessionFactoryImplementor) session.getSessionFactory();
        ConnectionProvider cp = sfi.getConnectionProvider();
        conn = cp.getConnection();
        preparedStatement = conn.prepareStatement("Select id, name from Custumer");
        ResultSet rs = preparedStatement.executeQuery();
        while (rs.next()) {
            System.out.print(rs.getInt(1));
            System.out.println(rs.getString(2));
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (preparedStatement != null) {
            preparedStatement.close();
        }
        if (conn != null) {
            conn.close();
        }
    }

0

यहाँ एक जावा 8 विधि है जिसका Connectionउपयोग EntityManagerवास्तव में इसके साथ अभी तक कुछ भी किए बिना उपयोग किया गया है:

private Connection getConnection(EntityManager em) throws SQLException {
    AtomicReference<Connection> atomicReference = new AtomicReference<Connection>();
    final Session session = em.unwrap(Session.class);
    session.doWork(connection -> atomicReference.set(connection));
    return atomicReference.get();
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.