java मैं एक जर्सी/एचके 2 एप्लिकेशन में एक इकाई प्रबंधन को कैसे ठीक से कॉन्फ़िगर करूँ?



jpa dependency-injection (1)

मेरे पास जर्सी-2 / एचके 2 आवेदन है जो जेपीए दृढ़ता का उपयोग करता है। EntityManager इस तरह स्टार्टअप पर बाध्य है

public MyApplication() {
    // ...
    register(new AbstractBinder() {
        @Override
        public void configure() {
          bindFactory(EmFactory.class)
            .to(EntityManager.class)
            .in(RequestScoped.class);
        }
    });
}

कारखाने वर्ग के साथ

public class EmFactory implements Factory<EntityManager> {

    private static final String PERSISTENCE_UNIT = "unit";

    private EntityManagerFactory emf;
    private CloseableService closeableService;

    @Inject
    public EmFactory(@Named(PERSISTENCE_UNIT) String persistenceUnit,
            CloseableService closeableService) {
        emf = Persistence.createEntityManagerFactory(persistenceUnit);
        this.closeableService = closeableService;
    }

    @Override
    public EntityManager provide() {
        final EntityManager entityManager = emf.createEntityManager();
        closeableService.add(new Closeable() {

            @Override
            public void close() throws IOException {
                if(entityManager.isOpen()) {
                    entityManager.close();
                }
            }
        });
        return entityManager;
    }

    @Override
    public void dispose(EntityManager entityManager) {
        if(entityManager.isOpen()) {
            entityManager.close();
        }
    }
}

यह काम करता है लेकिन फिर प्रत्येक अनुरोध के लिए मुझे पहले से पंजीकृत एक EntityManager के बारे में लॉग में एक चेतावनी मिलती है:

HHH000436: Entity manager factory name (unit) is already registered. \
  If entity manager will be clustered or passivated, specify a unique \
  value for property 'hibernate.ejb.entitymanager_factory_name'

मैं क्या गलत कर रहा हूं? एक जर्सी -2 / एचके 2 एप्लिकेशन में एंटिटी मैनेजर को आरंभ करने का सही तरीका क्या है?


एक विकल्प EMFactory (जो एक अनुरोध के दायरे में है) में एक नई EMFactory EntityManagerFactory बनाने के बजाय है, तो आप EntityManagerFactory लिए एक सिंगलटन कारखाना बना सकते हैं, फिर केवल EMFactory को EMFactory में EMFactory

public class EMFFactory implements Factory<EntityManagerFactory> {
    private final EntityManagerFactory emf;
    public EMFFactory (){
        emf = Persistence.createEntityManagerFactory(persistenceUnit);
    }
    public EntityManagerFactory provide() {
        return emf;
    }
    ...
}

public class EMFactory implements Factory<EntityManager> {
    private final EntityManager em;

    @Inject
    public EMFactory (EntityManagerFactory emf){
        em = emf.createEntityManager();
    }
    public EntityManager provide() {
        return em;
    }
    ...
}

इस सटीक क्रियान्वयन का परीक्षण नहीं किया है, लेकिन इसे इस तरह दिखना चाहिए। मैंने पहले इस पैटर्न का इस्तेमाल किया है

register(new AbstractBinder() {
    @Override
    public void configure() {
      bindFactory(EMFFactory.class).to(EntityManagerFactory.class).in(Singleton.class);
      bindFactory(EMFactory.class).to(EntityManager.class).in(RequestScoped.class);
    }
});

अद्यतन करें

उपर्युक्त उदाहरण के बारे में ध्यान देना एक बात यह है कि यह संसाधनों को साफ नहीं करता है, अर्थात EntityManager बंद होना चाहिए; यह स्वयं को बंद नहीं करेगा Factory कक्षा में एक dispose विधि है जिसे हमें ओवरराइड करने की आवश्यकता है, लेकिन मेरे अनुभव से, इसे जर्सी द्वारा कभी नहीं कहा जाता है

हम क्या कर सकते हैं [ CloseableService ] [1] में EntityManager को जोड़ते हैं

public class EMFactory implements Factory<EntityManager> {
    private final EntityManagerFactory emf;
    private final CloseableService closeService;

    @Inject
    public EMFactory (EntityManagerFactory emf, CloseableService closeService){
        this.emf = emf;
        this.closeService = closeService;
    }
    public EntityManager provide() {
        final EntityManager em = emf.createEntityManager();
        this.closeService.add(new Closeable(){
            @Override
            public void close() {
                em.close();
            }
        });
        return em;
    }
    ...
}

इस प्रकार EntityManager को अनुरोध के अंत में बंद करने के लिए सुनिश्चित किया गया है।





hk2