2010-05-10 11 views
18

कई फ़ोरम देखे लेकिन उत्तर नहीं मिला ... सरल सामग्री, @PostLoad के साथ एनोटेटेड विधि कभी भी नहीं आती है ... @EntityListeners के माध्यम से जोड़ा गया श्रोता लेकिन समस्या बनी हुई है। मैं सत्र कारखाना आधारित विन्यास का उपयोग कर रहा हूँ।हाइबरनेट @ पोस्टलोड कभी भी नहीं आ जाता है

उत्तर

15

ईजेबी 3 @PostLoad एनोटेशन SessionFactory आधारित कॉन्फ़िगरेशन का उपयोग करते समय काम नहीं करता है, पोस्ट-लोड विधि कभी कॉल नहीं की जाएगी।

या तो हाइबरनेट के Interceptors or events या EntityManager आधारित कॉन्फ़िगरेशन का उपयोग करें।

+2

कॉलबैक बिल्कुल जब SessionFactory का उपयोग कर काम कर सकते हैं। आपको बस उचित हाइबरनेट ईवेंट श्रोताओं को स्वयं सक्षम करना होगा। –

+0

यहां ईवेंट श्रोताओं को सक्षम करने का तरीका बताया गया है: https://n1njahacks.wordpress.com/2016/10/07/jpa-callbacks-with-hibernates-sessionfactory-and-no-entitymanager/ –

9

सत्र फ़ैक्टरी का उपयोग करते समय हाइबरनेट के इंटरसेप्टर या ईवेंट दृष्टिकोण के लिए एक विकल्प भी है: Lifecycle इंटरफ़ेस को कार्यान्वित करना।

+3

लेकिन इस बग से सावधान रहें: https: //hibernate.onjira।कॉम/ब्राउज/एचएचएच -6043 जो लाइफसाइकिल.ऑनलोड के लिए भी है (संग्रह शुरू होने से पहले बुलाया जाता है - जब तक कि इसे हाइबरनेट 4.1.8 में तय नहीं किया जाता) – Jakub

1

या जेपीए कॉलबैक को संभालने वाले हाइबरनेट ईवेंट श्रोताओं को सक्षम करें। यही वह है जो एचईएम करता है। यह कैसे किया जाता है हाइबरनेट 3 और हाइबरनेट 4 के बीच अलग है (आपने कभी नहीं बताया कि आप किस संस्करण का उपयोग कर रहे हैं); (ए) घटना श्रोताओं को शामिल करने के विवरण के लिए प्रलेखन की जांच करें और (बी) श्रोताओं के कस्टम सेट को कैसे निर्दिष्ट करें।

+0

शायद मैं मोटा हूं, लेकिन मुझे मुश्किल समय मिल रहा है कि कैसे इसे हाइबरनेट 4 के लिए प्रलेखन में करें। – David

2

मैं इस फैक्ट्री का उपयोग करके हाइबरनेट 4 पर इस काम को करने के लिए भी संघर्ष कर रहा हूं।

मुझे समाधान बहुत सरल मिला लेकिन इंटीग्रेटर (स्पष्ट रूप से सत्रफैक्टरी और श्रोताओं से निपटने के लिए हाइबरनेट 4 का तरीका) का उपयोग करके कहीं भी दस्तावेज नहीं किया गया। हाइबरनेट-entitymanager परियोजना EJB3 के एनोटेशन ... लिंक करने के लिए सत्र कारखाने के लिए @PostLoad, आवश्यक श्रोताओं को जोड़ने के लिए एक इंटीग्रेटर प्रदान करता है। बस JpaIntegratorएसपीआई तरीका घोषित करें।

Concretely, बस META-INF/सेवाओं फ़ोल्डर में org.hibernate.integrator.spi.Integrator नाम की एक फ़ाइल जोड़ सकते हैं और (उस में कार्यान्वयन वर्ग घोषित org.hibernate.ejb.event.JpaIntegrator)

+0

अच्छा समाधान। FYI, Hibernate 4.3.5 के रूप में, फ़ाइल की सामग्री "org.hibernate.jpa.event.spi.JpaIntegrator" होना चाहिए। –

+0

यह वह समाधान है जिसके साथ मैं भी गया था, हालांकि मुझे पता चला कि यह हाइबरनेट 5 में फ्लश कैस्केड तोड़ देगा। फिक्स के लिए नीचे मेरा जवाब देखें। –

+0

@ मैट मैं इसे एक बहुत पुराना सवाल जानता हूं लेकिन मुझे यह मेटा-आईएनएफ/सेवाएं कहां मिलनी चाहिए? मैं इसे केवल उस फ़ोल्डर में ढूंढ सकता हूं जहां मैंने हाइबरनेट डाउनलोड किया और परिवर्तन करने के बाद, यह अभी भी काम नहीं करता है। –

3

यहाँ 5.

हाइबरनेट के IntegratorServiceImpljava.util.ServiceLoader API का उपयोग करता हाइबरनेट में जेपीए पद सेशन एनोटेशन सक्षम करने के लिए कैसे, तो हम हमचाहते org.hibernate.integrator.spi.Integrator कार्यान्वयन की एक अतिरिक्त सूची निर्दिष्ट कर सकते है उपयोग करने के लिए।

# This allows us to use JPA-style annotation on entities, such as @PostLoad 
our.custom.JpaAnnotationsIntegrator 

तुम भी सुनिश्चित करना है कि 'hibernate-entitymanager' उपयुक्त संस्करण के जार अपने classpath पर है की आवश्यकता होगी:

सभी हम क्या करने की जरूरत META-INF/services/org.hibernate.integrator.spi.Integrator में एक सेवा प्रदाता निर्दिष्ट है।

our.custom.JpaAnnotationsIntegrator (org.hibernate.jpa.event.spi.JpaIntegrator से लिया गया):

package our.custom; 

import org.hibernate.annotations.common.reflection.ReflectionManager; 
import org.hibernate.boot.Metadata; 
import org.hibernate.boot.internal.MetadataImpl; 
import org.hibernate.engine.spi.SessionFactoryImplementor; 
import org.hibernate.event.service.spi.EventListenerRegistry; 
import org.hibernate.event.spi.EventType; 
import org.hibernate.integrator.spi.Integrator; 
import org.hibernate.jpa.event.internal.core.JpaPostDeleteEventListener; 
import org.hibernate.jpa.event.internal.core.JpaPostInsertEventListener; 
import org.hibernate.jpa.event.internal.core.JpaPostLoadEventListener; 
import org.hibernate.jpa.event.internal.core.JpaPostUpdateEventListener; 
import org.hibernate.jpa.event.internal.jpa.CallbackBuilderLegacyImpl; 
import org.hibernate.jpa.event.internal.jpa.CallbackRegistryImpl; 
import org.hibernate.jpa.event.spi.jpa.CallbackBuilder; 
import org.hibernate.jpa.event.spi.jpa.ListenerFactory; 
import org.hibernate.jpa.event.spi.jpa.ListenerFactoryBuilder; 
import org.hibernate.mapping.PersistentClass; 
import org.hibernate.service.spi.SessionFactoryServiceRegistry; 

/** 
* This integrator allows us to use JPA-style post op annotations on Hibernate entities. 
* 

* This integrator is loaded by <code>org.hibernate.integrator.internal.IntegratorServiceImpl</code> from 
* <code>META-INF/services/org.hibernate.integrator.spi.Integrator</code> file. 
* 

* <b>Note</b>: This code is lifted directly from <code>org.hibernate.jpa.event.spi.JpaIntegrator</code> 
* 
* @author Val Blant 
*/ 
public class JpaAnnotationsIntegrator implements Integrator { 
    private ListenerFactory jpaListenerFactory; 
    private CallbackBuilder callbackBuilder; 
    private CallbackRegistryImpl callbackRegistry; 

    @Override 
    public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { 
     final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService(EventListenerRegistry.class); 

     this.callbackRegistry = new CallbackRegistryImpl(); 

     // post op listeners 
     eventListenerRegistry.prependListeners(EventType.POST_DELETE, new JpaPostDeleteEventListener(callbackRegistry)); 
     eventListenerRegistry.prependListeners(EventType.POST_INSERT, new JpaPostInsertEventListener(callbackRegistry)); 
     eventListenerRegistry.prependListeners(EventType.POST_LOAD, new JpaPostLoadEventListener(callbackRegistry)); 
     eventListenerRegistry.prependListeners(EventType.POST_UPDATE, new JpaPostUpdateEventListener(callbackRegistry)); 

     // handle JPA "entity listener classes"... 
     final ReflectionManager reflectionManager = ((MetadataImpl) metadata) 
       .getMetadataBuildingOptions() 
       .getReflectionManager(); 

     this.jpaListenerFactory = ListenerFactoryBuilder.buildListenerFactory(sessionFactory.getSessionFactoryOptions()); 
     this.callbackBuilder = new CallbackBuilderLegacyImpl(jpaListenerFactory, reflectionManager); 
     for (PersistentClass persistentClass : metadata.getEntityBindings()) { 
      if (persistentClass.getClassName() == null) { 
       // we can have non java class persisted by hibernate 
       continue; 
      } 
      callbackBuilder.buildCallbacksForEntity(persistentClass.getClassName(), callbackRegistry); 
     } 
    } 

    @Override 
    public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { 
     if (callbackRegistry != null) { 
      callbackRegistry.release(); 
     } 
     if (callbackBuilder != null) { 
      callbackBuilder.release(); 
     } 
     if (jpaListenerFactory != null) { 
      jpaListenerFactory.release(); 
     } 
    } 
} 
संबंधित मुद्दे