2010-05-10 39 views
18

Đã xem nhiều diễn đàn nhưng chưa tìm thấy câu trả lời ... Các công cụ đơn giản, phương thức được chú thích với @PostLoad chưa bao giờ được gọi ... đã thêm người nghe qua @EntityListeners nhưng vẫn còn vấn đề. Tôi đang sử dụng cấu hình dựa trên SessionFactory.Hibernate @PostLoad không bao giờ được gọi

Trả lời

15

Chú thích EJB3 @PostLoad không hoạt động khi sử dụng cấu hình dựa trên SessionFactory, phương pháp sau tải sẽ không bao giờ được gọi.

Hoặc sử dụng cấu hình dựa trên Interceptors or events của Hibernate hoặc EntityManager.

+2

Các callbacks hoàn toàn có thể làm việc khi sử dụng SessionFactory. Bạn chỉ cần bật trình nghe sự kiện Hibernate thích hợp. –

+0

Dưới đây là cách bật trình xử lý sự kiện: https://n1njahacks.wordpress.com/2016/10/07/jpa-callbacks-with-hibernates-sessionfactory-and-no-entitymanager/ –

9

Ngoài ra còn có một giải pháp thay thế cho công cụ đánh chặn hoặc sự kiện của hibernate khi sử dụng SessionFactory: triển khai giao diện Lifecycle.

+3

Nhưng hãy cẩn thận với lỗi này: https: //hibernate.onjira.com/browse/HHH-6043 cũng giữ cho Lifecycle.onLoad (được gọi trước khi bộ sưu tập được khởi tạo - cho đến khi nó được sửa trong Hibernate 4.1.8) – Jakub

1

Hoặc bật trình xử lý sự kiện Hibernate xử lý cuộc gọi lại JPA. Đó chính xác là những gì HEM làm. Làm thế nào mà được thực hiện là khác nhau giữa Hibernate 3 và Hibernate 4 (bạn không bao giờ đề cập đến phiên bản bạn đang sử dụng); kiểm tra tài liệu để biết chi tiết về (a) những người nghe sự kiện có liên quan và (b) cách chỉ định tập hợp người nghe tùy chỉnh.

+0

Có lẽ tôi dày, nhưng tôi đang gặp khó khăn trong việc tìm cách làm điều này trong tài liệu hướng dẫn cho Hibernate 4. – David

2

Tôi cũng đã đấu tranh để thực hiện công việc này trên Hibernate4, sử dụng nhà máy phiên.

Tôi đã tìm thấy giải pháp khá đơn giản nhưng không được ghi lại ở bất cứ đâu bằng Trình tích hợp (Dường như cách của Hibernate4 để xử lý SessionFactory và người nghe). Dự án hibernate-entitymanager cung cấp Trình tích hợp để thêm người nghe cần thiết để liên kết chú thích EJB3 @PostLoad, ... với nhà máy phiên. Chỉ cần khai báo lớp học JpaIntegrator cách SPI.

Cụ thể, chỉ cần thêm một file có tên org.hibernate.integrator.spi.Integrator trong thư mục/dịch vụ thư mục META-INF và tuyên bố các lớp thực hiện trong nó (org.hibernate.ejb.event.JpaIntegrator)

+0

Giải pháp tốt. FYI, như của Hibernate 4.3.5, nội dung của tệp phải là "org.hibernate.jpa.event.spi.JpaIntegrator". –

+0

Đây là giải pháp tôi đã đi với là tốt, mặc dù tôi thấy rằng nó sẽ phá vỡ thác thác trong Hibernate 5. Xem câu trả lời của tôi dưới đây để sửa chữa. –

+0

@ Tôi biết một câu hỏi rất cũ nhưng tôi nên tìm META-INF/Dịch vụ này ở đâu? tôi chỉ có thể tìm thấy nó trong thư mục mà tôi tải về hibernate và sau khi thực hiện thay đổi, nó vẫn không hoạt động. –

3

Dưới đây là làm thế nào để kích hoạt tính năng chú thích bài op JPA trong Hibernate 5.

Hibernate của IntegratorServiceImpl sử dụng java.util.ServiceLoader API, vì vậy chúng tôi có thể xác định một danh sách bổ sung của org.hibernate.integrator.spi.Integrator triển khai chúng ta muốn SessionFactory để sử dụng.

Tất cả chúng ta cần phải làm là chỉ định một nhà cung cấp dịch vụ trong META-INF/services/org.hibernate.integrator.spi.Integrator:

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

Bạn cũng sẽ cần phải đảm bảo rằng ‘hibernate-entitymanager‘lọ phiên bản phù hợp là trên classpath của bạn.

our.custom.JpaAnnotationsIntegrator (lấy từ 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(); 
     } 
    } 
} 
Các vấn đề liên quan