2016-06-26 12 views
5

के साथ हाइबरनेट डीएओ को कैसे कार्यान्वित करें मुझे जेनिक्स के साथ हाइबरनेट डीएओ बनाने के तरीके पर कुछ ट्यूटोरियल मिले हैं, लेकिन वे सभी के बजाय EntityManager का उपयोग करते हैं। मेरा सवाल है कि SessionFactory का उपयोग कर जेनेरिक के साथ डीएओ कैसे बनाया जाए। मैं अब तक नीचे है:जेनेरिक

इंटरफ़ेस:

public interface GenericDao<T> { 

    public void save(T obj); 
    public void update(T obj); 
    public void delete(T obj); 
    public T findById(long id); 
} 

कक्षा:

@Repository 
public class GenericDaoImpl<T> implements GenericDao<T> { 

    @Autowired 
    private SessionFactory sessionFactory; 

    public void save(T obj) { 
     Session session = sessionFactory.openSession(); 
     Transaction tx = null; 
     try { 
      tx = session.beginTransaction(); 
      session.save(obj); 
      tx.commit(); 
     } catch (HibernateException e) { 
      if(tx != null) 
       tx.rollback(); 
      e.printStackTrace(); 
     } finally { 
      session.close(); 
     } 

    } 

    public void update(T obj) { 
     Session session = sessionFactory.openSession(); 
     Transaction tx = null; 
     try { 
      tx = session.beginTransaction(); 
      session.update(obj); 
      tx.commit(); 
     } catch (HibernateException e) { 
      if(tx != null) 
       tx.rollback(); 
      e.printStackTrace(); 
     } finally { 
      session.close(); 
     } 

    } 

    public void delete(T obj) { 
     Session session = sessionFactory.openSession(); 
     Transaction tx = null; 
     try { 
      tx = session.beginTransaction(); 
      session.delete(obj); 
      tx.commit(); 
     } catch (HibernateException e) { 
      if(tx != null) 
       tx.rollback(); 
      e.printStackTrace(); 
     } finally { 
      session.close(); 
     } 

    } 

    public T findById(long id) { 
     // ?? 
     return null; 
    } 

मैं अनिश्चित कैसे findById के बारे में जेनरिक का उपयोग कर जाने के लिए कर रहा हूँ। मेरा मानना ​​है कि अन्य विधियां सही हैं, लेकिन अगर मैं गलत हूं तो मुझे सही करें।

साइड क्वेस्ट:EntityManagerSessionFactory का उपयोग करने से अधिक फायदेमंद है? मैंने विषय पर कुछ पोस्ट देखी, लेकिन कुछ और राय चाहिए।

+0

जावा में, जेनेरिक को मिटाकर कार्यान्वित किया जाता है और आपके औपचारिक प्रकार पैरामीटर 'टी' रन टाइम पर' ऑब्जेक्ट 'बन जाता है। दूसरे शब्दों में, रन टाइम प्रकार 'टी' पर मौजूद नहीं है। किसी भी जेनेरिक विधि जो एक नए खनन 'टी' आवृत्ति को वापस लाती है, इसलिए उसे रन टाइम टाइप टोकन की आवश्यकता होती है, जिसकी विधि उस उदाहरण के प्रकार को प्रतिबिंबित करने के लिए उपयोग कर सकती है जिसे इसे बनाने की आवश्यकता होगी। 'FindById (...)' के लिए एक और व्यावहारिक हस्ताक्षर इसलिए सार्वजनिक टी खोज है (कक्षा कक्षा, लंबी आईडी) '। – scottb

+0

@scottb तो कक्षा टोकन का उपयोग यह निर्धारित करने के लिए किया जाएगा कि किस प्रकार की ऑब्जेक्ट को वापस करने की आवश्यकता है? मैं इस बारे में बिल्कुल कैसे जाऊं?'EntityManager' उदाहरणों के साथ, मैंने' entityManager.find (type.class, id) देखा; 'लेकिन मुझे' सत्र फ़ैक्टरी 'के साथ ऐसा करने का तरीका नहीं है। –

+0

यदि आपको जिस प्रकार की वापसी की आवश्यकता है, उसके पास कोई तर्क-तर्क कन्स्ट्रक्टर नहीं है, तो मनमानी प्रकार 'टी' के नए उदाहरण को गतिशील रूप से टकसाल करने का सबसे आसान तरीका 'कक्षा ' की 'newInstance()' विधि का उपयोग करना होगा, जैसे। 'टी myObj = class.newInstance();'। अन्यथा, आपको तर्क के साथ उचित कन्स्ट्रक्टर का आह्वान करने के लिए 'कक्षा ' ऑब्जेक्ट के माध्यम से प्रतिबिंब का उपयोग करने की आवश्यकता हो सकती है। ऐसी विधि में, 'कक्षा कक्षा' में 'कक्षा' एक * रन टाइम प्रकार टोकन * की भूमिका निभाता है। जावा में, ये कभी-कभी जरूरी होते हैं क्योंकि जेनेरिक प्रकार रन टाइम पर मौजूद नहीं होते हैं। – scottb

उत्तर

5

आपको उस विधि के भीतर से Class<T> तक पहुंच की आवश्यकता है। आपके पास दो विकल्प है, तो आप विधि में Class<T> पारित कर सकते हैं:

public T findById(long id, Class<T> clazz) { 
    // method implementation 
} 

या आप वर्ग के निर्माता में Class<T> पारित कर सकते हैं विधि में इस्तेमाल के लिए:

@Repository 
public class GenericDaoImpl<T> implements GenericDao<T> { 

    private Class<T> clazz; 

    protected GenericDaoImpl(Class<T> clazz) { 
     this.clazz = clazz; 
    } 

    // other methods omitted 

    public T findById(long id) { 
     // method implementation 
    } 
} 

और उपवर्गों से होकर गुजरेगा सुपर क्लास में अपने वर्ग:

public class UserDao extends GenericDaoImpl<User> { 
    public UserDao() { 
     super(User.class); 
    } 
} 

फिर, अपने clazz उदाहरण का उपयोग करते हुए आप इकाई अपने सामान्य विधि का उपयोग कर प्राप्त कर सकते हैं Session#get विधि:

T entity = session.get(clazz, id); 

अधिक जानकारी के लिए निम्नलिखित प्रश्न देखें:


जहाँ तक पक्ष प्रश्न के रूप में, EntityManager का हिस्सा है जेपीए (जा वीए पर्सिस्टेंस एपीआई)। हाइबरनेट एपीआई के बजाए जावा एपीआई विनिर्देश का उपयोग करके अपने एप्लिकेशन को विकसित करना आपके एप्लिकेशन को हाइबरनेट पर निर्भर नहीं होने देता है। यह आपको लोकप्रिय जेपीए कार्यान्वयन जैसे हाइबरनेट, ओपनजेपीए, या टॉपलिंक के बीच स्विच करने और आपके कोड में बदलाव किए बिना स्विच करने की अनुमति देता है।

This question इस अंतर पर अधिक जानकारी है।

+0

धन्यवाद! एक और पक्ष सवाल - क्या 'सत्र प्रबंधन' पर 'EntityManager' का उपयोग करने का कोई कारण है और इसके विपरीत? या वे दोनों मुख्य रूप से एक ही काम करते हैं? –

+0

उस 'सुपर (User.class); 'लाइन को जोड़ने की कोई आवश्यकता नहीं है। अमूर्त जेनेरिक क्लास अपने बच्चों के वर्गों के प्रकार के तर्क को देख सकता है, जैसा कि यहां देखा गया है: https://github.com/acdcjunior/acdcjunior-github-io-example-projects/blob/master/spring-mvc-jpa-mockito -पिलोतो/src/main/java/net/acdcjunior/piloto/infrastructure/jpa/jpaAbstractRepository.java # L43 – acdcjunior

+0

@ जेकमिलर 'EntityManager' जेपीए है,' सत्र कारखाना 'हाइबरनेट (एक जेपीए कार्यान्वयन) है। ये एक ही चीज नहीं हैं। 'EntityManager' (जेपीए) 'सत्र' (हाइबरनेट) 'EntityManagerFactory' (जेपीए) के रूप में' सत्र कारखाना '(हाइबरनेट) है। आमतौर पर, हम जेपीए पसंद करते हैं। लेकिन यदि आप कभी भी हाइबरनेट से दूसरे (जैसे टॉपलिंक) में कार्यान्वयन को बदलने की योजना नहीं बनाते हैं, तो इससे कोई फर्क नहीं पड़ता (मेरा मतलब है, इस मामले में, जो कुछ भी आप पसंद करते हैं) का उपयोग करें। – acdcjunior

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