Miró muchos foros pero no encontró respuesta ... Cosas simples, el método anotado con @PostLoad nunca se invoca ... se agregó oyente a través de @EntityListeners pero el problema persiste. Estoy usando la configuración basada en SessionFactory.Hibernate @PostLoad nunca se invoca
Respuesta
La anotación EJB3 @PostLoad
no funciona cuando se utiliza una configuración basada en SessionFactory
, nunca se llamará al método posterior a la carga.
O use la configuración basada en Interceptors or events de Hibernate o EntityManager
.
También existe una alternativa al enfoque de interceptores o eventos de hibernate cuando se usa SessionFactory: implementación de la interfaz Lifecycle.
Pero tenga cuidado con este error: https: //hibernate.onjira.com/browse/HHH-6043, que también es válida para Lifecycle.onLoad (se invoca antes de que se inicien las colecciones, hasta que se haya solucionado en Hibernate 4.1.8) – Jakub
O active los detectores de eventos de Hibernate que manejan devoluciones de llamada JPA. Eso es exactamente lo que HEM hace. Cómo se hace eso es diferente entre Hibernate 3 e Hibernate 4 (nunca mencionaste qué versión estás usando); revise la documentación para obtener detalles sobre (a) los oyentes del evento involucrados y (b) cómo especificar un conjunto de oyentes personalizado.
Tal vez soy grueso, pero me está costando mucho encontrar cómo hazlo en la documentación de Hibernate 4. – David
También he estado luchando para hacer que esto funcione en Hibernate4, usando la fábrica de sesiones.
Encontré la solución bastante simple pero no documentada en ninguna parte usando Integrator (aparentemente la forma de Hibernate4 de tratar con SessionFactory y los oyentes). El proyecto hibernate-entitymanager proporciona un integrador para agregar los oyentes necesarios para vincular las anotaciones de EJB3 @PostLoad, ... a la fábrica de sesiones. Simplemente declare la clase JpaIntegratorSPI manera.
Concretamente, sólo tiene que añadir un archivo llamado org.hibernate.integrator.spi.Integrator en la carpeta/serviciosMETA-INF y declarar la clase de implementación en ella (org.hibernate.ejb.event.JpaIntegrator)
Buena solución. FYI, a partir de Hibernate 4.3.5, el contenido del archivo debe ser "org.hibernate.jpa.event.spi.JpaIntegrator". –
Esta es la solución que también fui, aunque descubrí que romperá las cascadas de Hibernate 5. Consulte mi respuesta a continuación para obtener una solución. –
@Matt sé que es una pregunta muy antigua, pero ¿dónde debería encontrar este META-INF/Services? Solo puedo encontrarlo en la carpeta donde descargué hibernación y después de hacer cambios, todavía no funciona. –
así es como para permitir anotaciones post op de la APP en Hibernate 5.
de IntegratorServiceImpl
Hibernate utiliza la API de java.util.ServiceLoader
, por lo que podemos especificar una lista adicional de org.hibernate.integrator.spi.Integrator
implementaciones queremos que el SessionFactory
para usar.
Todo lo que tenemos que hacer es especificar un proveedor de servicios en META-INF/services/org.hibernate.integrator.spi.Integrator
:
# This allows us to use JPA-style annotation on entities, such as @PostLoad
our.custom.JpaAnnotationsIntegrator
También tendrá que asegurarse de que ‘hibernate-entitymanager
‘tarro de la versión adecuada está en la ruta de clases.
our.custom.JpaAnnotationsIntegrator
(tomado de 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();
}
}
}
- 1. GridView onItemClickListener nunca se invoca
- 2. onFinishInflate() nunca se llama
- 3. Anotaciones de datos personalizados IsValid nunca se invoca. (ASP.NET MVC 2 .NET 4)
- 4. Método Spring MVC @ExceptionHandler en el controlador que nunca se invoca
- 5. ¡DateTimePicker nunca se actualiza!
- 6. ¿Qué constructor se invoca aquí?
- 7. PictureCallback.onPictureTaken nunca se llamó
- 8. IMetadataAware.OnMetadataCreated nunca se llama
- 9. onLocationChanged() nunca se llamó
- 10. onActivityResult nunca se llamó
- 11. TaskScheduler.UnobservedTaskException nunca se llama
- 12. Ventana emergente nunca se cierra
- 13. Actividad OnDestroy nunca se llamó?
- 14. Método didUpdateLocation Nunca se llamó
- 15. Fragment's onSaveInstanceState() nunca se llama
- 16. constructor de copia no se invoca
- 17. Qué evento se invoca cuando pulsamos UISearchBar
- 18. ¿Se invoca String.length() para una cadena final?
- 19. Suprimir "nunca se usa" y "nunca se asigna a" advertencias en C#
- 20. NSFilePresenter -presentedSubitemDidAppearAtURL: el método nunca se llama
- 21. Android: nunca se llama a onTouch()?
- 22. matraz de WTF - validate_on_submit() nunca se ejecuta
- 23. ¿Por qué paint()/paintComponent() nunca se llama?
- 24. C# valor se declara pero nunca utilizado
- 25. Android: Parcelable.writeToParcel y Parcelable.Creator.createFromParcel nunca se llaman
- 26. Android: onPreviewFrame nunca se llamó sin SurfaceView
- 27. ¿Por qué mi destructor nunca se llama?
- 28. Servicio de intenciones que nunca se llama
- 29. ¿Por qué mi destructor nunca se ejecuta?
- 30. AVCaptureOutput captureStillImageAsynchronouslyFromConnection nunca se completa el iPhone5
Las devoluciones de llamada puede trabajar absolutamente cuando se utiliza SessionFactory. Simplemente tiene que habilitar los propios detectores de eventos Hibernate. –
Así es cómo habilitar los detectores de eventos: https://n1njahacks.wordpress.com/2016/10/07/jpa-callbacks-with-hibernates-sessionfactory-and-no-entitymanager/ –