2011-07-15 12 views
9

से एक जेडीबीसी कनेक्शन ऑब्जेक्ट प्राप्त करें एक स्टेटलेस सत्र बीन में EntityManager इंजेक्शन दिया गया है लेकिन मैं डीबी प्रक्रिया का आह्वान करने के लिए Connection ऑब्जेक्ट को पकड़ना चाहता हूं। क्या इसका कोई समाधान है?एक स्टेटलेस बीन

+0

जेपीए एपीआई, ऐसी बात की अनुमति नहीं है। – DataNucleus

उत्तर

15

यह जेपीए प्रदाता विशिष्ट कोड होने जा रहा है। आम तौर पर यह EntityManager कक्षा पर unwrap() का आह्वान करके किया जाता है।

जेपीए 2,0

entityManager.getTransaction().begin(); 
java.sql.Connection connection = entityManager.unwrap(java.sql.Connection.class); // unwraps the Connection class. 
... 
entityManager.getTransaction().commit(); 

:

आप EclipseLink, निम्नलिखित कोड (EclipseLink wiki से) का उपयोग कर रहे हैं, तो उपयोगी होगा (यदि आप एक आवेदन से प्रबंधित EntityManager उपयोग कर रहे हैं) जेपीए 1,0

entityManager.getTransaction().begin(); 
UnitOfWork unitOfWork = (UnitOfWork)((JpaEntityManager)entityManager.getDelegate()).getActiveSession(); 
unitOfWork.beginEarlyTransaction(); 
Accessor accessor = unitOfWork.getAccessor(); 
accessor.incrementCallCount(unitOfWork.getParent()); 
accessor.decrementCallCount(); 
java.sql.Connection connection = accessor.getConnection(); 
... 
entityManager.getTransaction().commit(); 

ध्यान दें, कि जेपीए 2.0 के लिए प्रदान की समाधान एक PersistenceException संदेश

युक्त साथ हाइबरनेट 3.6.5 के लिए असफल हो जायेगी

हाइबरनेट खोलने नहीं कर सकता इंटरफ़ेस java.sql.Connection

उपयोग कोड Skaffman द्वारा प्रदान की यह काम करने के लिए प्राप्त करने के लिए हाइबरनेट के खिलाफ (कंटेनर प्रबंधित दृढ़ता संदर्भों के लिए भी 3.6.5 के तहत काम करने के लिए सत्यापित)।

हालांकि, एक्लिप्ससेंक विकी जानकारी के एक उपयोगी बिट को इंगित करता है - यदि आप जेटीए प्रबंधित डेटा स्रोत का उपयोग कर रहे हैं, तो आपको इसे @Resource एनोटेशन का उपयोग करके इंजेक्शन देना चाहिए या जेएनडीआई लुकअप का उपयोग करके इसे पुनर्प्राप्त करना चाहिए। जब तक आपको डेटाबेस के खिलाफ लेनदेन संबंधी कार्य करने की आवश्यकता होती है, तब तक यह असंभव है कि आप डेटा स्रोत या मौजूदा एक से नया कनेक्शन प्राप्त कर रहे हैं; अधिकांश कनेक्शन पूल वैसे भी वही कनेक्शन प्रदान करेंगे जो वर्तमान धागे से जुड़ा हुआ है (यानी इकाई प्रबंधक द्वारा पहले से उपयोग किया जा रहा है)। इसलिए आप इकाई प्रबंधक को इस तरह से खोलने से बचेंगे, और डेटाबेस के खिलाफ लेनदेन संबंधी गतिविधि भी करेंगे; याद रखें कि दृढ़ता संदर्भ कैश, और यदि आप ऐसा करते हैं तो एक दूसरे-स्तर के कैश को सिंक्रनाइज़ नहीं किया जा सकता है।

+0

अनचाप (java.sql.Connection.class) ओपनजेपीए (कम से कम 2.1.1) –

+0

@ पवेल में भी काम नहीं करता है, ऐसा लगता है कि यह 2.2.0 में ["निश्चित" है) (https: //issues.apache .org/jira/ब्राउज़/OPENJPA-1803)। –

+0

धन्यवाद! अभी तक उन्होंने अभी तक 2.2.0 जारी नहीं किया है :) –

2

आप entitymanager.getDelegate() या entitymanager.unwrap का उपयोग कर अंतर्निहित प्रतिनिधि रखना चाहिए (जो बेहतर तरीका है), विशिष्ट कार्यान्वयन करने के लिए इसे डाली (Hibernate में यह Session कहा जाता है)। फिर आप connection() विधि को कॉल कर सकते हैं। ध्यान रखें कि इसे बहिष्कृत किया गया है, इसके बजाय Work कक्षा का उपयोग करें। here और पढ़ें।

7

जेपीए एपीआई ही इस पेशकश करने के लिए आश्चर्यजनक रूप से नहीं प्रतीत नहीं होता है, लेकिन अगर आप जोड़े को करने को तैयार हैं विशिष्ट कार्यान्वयन को अपने कोड, तो आप इस (हाइबरनेट) की तरह कुछ का उपयोग कर सकते हैं:

Session hibernateSession = entityManager.unwrap(Session.class); 
Connection jdbcConnection = hibernateSession.connection(); 

ध्यान दें कि Session.connection() को हाइबरनेट 4 में हटाने के लिए बहिष्कृत किया गया है। इसके बजाय Session.doWork() का उपयोग करने पर विचार करें।

5

हाइबरनेट में, समाधान skaffman द्वारा पोस्ट की गई निम्न त्रुटि संदेश के परिणामस्वरूप:

हाइबरनेट वर्ग org.hsqldb खोलने नहीं कर सकता।सत्र

मैं इसे SessionImpl बजाय सत्र का उपयोग कर काम करने के लिए मिला:

Connection connection = entityManager().unwrap(SessionImpl.class).connection(); 

Session.doWork (का उपयोग कर समस्या को हल करने का एक उदाहरण है) इस प्रकार है:

private void executeNative(final String query) { 
    Session session = entityManager.unwrap(Session.class); 
    session.doWork(new Work() { 

     @Override 
     public void execute(Connection connection) throws SQLException { 
      Statement s = null; 
      try { 
       s = connection.createStatement(); 
       s.executeUpdate(query); 
      } 
      finally { 
       if (s != null) { 
        s.close(); 
       } 
      } 
     } 

    }); 
} 
+0

लौटाता है, आपको इसे "org.hibernate.Session" पर डालना चाहिए और "org.hsqldb.Session" नहीं – dulon

1

यह अजीब काम करता है और यदि आवश्यक हो तो आप कहीं और कनेक्शन ऑब्जेक्ट का उपयोग कर सकते हैं

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

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

0

नीचे कोड है जो मेरे लिए काम करता है। हम जेपीए 1.0, अपाचे ओपनजेपीए कार्यान्वयन का उपयोग करते हैं।

import java.sql.Connection; 
import org.apache.openjpa.persistence.OpenJPAEntityManager; 
import org.apache.openjpa.persistence.OpenJPAPersistence; 



public final class MsSqlDaoFactory { 


    public static final Connection getConnection(final EntityManager entityManager) { 
      OpenJPAEntityManager openJPAEntityManager = OpenJPAPersistence.cast(entityManager); 
      Connection connection = (Connection) openJPAEntityManager.getConnection(); 
      return connection; 

    } 

} 
0

JPA2.0 में, अगर जरूरत JDBC पोर डीटीओ nomodel या क्वेरी अधिक परिसर के लिए इकाई है। कभी कभी जेपीए सब नहीं है ...

मुझे आशा है कि यह तुम्हारी मदद करेगा: हालांकि JDO एपीआई करता

Statement statement = null; 
EntityManager em = null; 
em = emf.createEntityManager(); 
EntityTransaction et = em.getTransaction(); 

if(!et.isActive()) { 
    et.begin(); 
} 

java.sql.Connection connection = em.unwrap(java.sql.Connection.class); 

    String qquerry="SELE ... 
    try { 
     statement = connection.createStatement(); 
     ResultSet rs = statement.executeQuery(qquerry);                

     if (!rs.next()) { 
      return null; 
     } 
     else{ 
      wwwwas=rs.getString(4);         
     }   
     statement.close(); 
     } 
    catch (SQLException e) { 
     System.out.println("\n b-03:"+e); 
     throw new RuntimeException(e.getMessage(), e); 
    } 
    finally { 
     try { 
      // em.getTransaction().commit(); 
      if(connection != null) 
      connection.close(); 
     } 
     catch (Exception e) { 
      throw new RuntimeException(e.getMessage(), e); 
     } 
    } 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^