春季-如何在没有活动会话的情况下将实体侦听器添加到JPA(EclipseLink)实体?
作者:互联网
我正在弹簧豆中尝试执行以下操作:
@PostConstruct
public void registerTorchEntityListeners()
{
Session session = entityManager.unwrap(Session.class);
for (EntityType<?> entity : entityManager.getMetamodel().getEntities())
{
if (entity.getJavaType().isAnnotationPresent(TorchEntityListeners.class))
{
TorchEntityListeners annotation = (TorchEntityListeners) entity.getJavaType().getAnnotation(TorchEntityListeners.class);
for (Class listenerClass : annotation.value())
{
Map<String, DescriptorEventListener> map = applicationContext.getBeansOfType(listenerClass);
for (DescriptorEventListener listenerBean : map.values())
{
session.getClassDescriptor(entity.getClass()).getEventManager().addListener(listenerBean);
}
}
}
}
}
问题是我得到以下异常,因为(我认为)我不在事务中,因此没有可用的会话来获取ClassDescriptor,因此我可以将侦听器添加到特定实体:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'torchEntityListenerConfigurer': Invocation of init method failed; nested exception is java.lang.IllegalStateException: No transactional EntityManager available
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:133)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:396)
基本上,我正在尝试执行等效于EclipseLink的操作:http://invariantproperties.com/2013/09/29/spring-injected-beans-in-jpa-entitylisteners/.我宁愿使用侦听器为实体添加注释,而不是执行以下操作:Injecting a Spring dependency into a JPA EntityListener.
有什么想法吗?
解决方法:
当然,我会在悬赏30分钟后解决:)
我终于通过从EntityManagerFactory中的连线获取EntityManager而不是使用@PersistenceContext将其注入到TorchEntityListenerConfigurer中来使其工作
这是有效的解决方案……效果很好!
这是配置:
<bean id="approvalEntityListener" class="com.prometheus.torchlms.core.activity.approval.ApprovalEntityListener">
<property name="activityRepository" ref="activityRepository" />
<property name="notificationFactory" ref="notificationFactory" />
<property name="notificationService" ref="notificationService" />
</bean>
<bean id="springEntityListenerConfigurer" class="com.prometheus.torchlms.core.SpringEntityListenerConfigurer">
<constructor-arg ref="entityManagerFactory" />
</bean>
这是魔术发生的地方(如果这对某人有用):
public class SpringEntityListenerConfigurer implements ApplicationContextAware
{
private ApplicationContext applicationContext;
private EntityManagerFactory entityManagerFactory;
public SpringEntityListenerConfigurer(EntityManagerFactory entityManagerFactory)
{
this.entityManagerFactory = entityManagerFactory;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException
{
this.applicationContext = applicationContext;
}
@PostConstruct
public void registerTorchEntityListeners()
{
//entityManager.
EntityManager entityManager = entityManagerFactory.createEntityManager();
Session session = entityManager.unwrap(Session.class);
for (EntityType<?> entity : entityManagerFactory.getMetamodel().getEntities())
{
if (entity.getJavaType().isAnnotationPresent(SpringEntityListeners.class))
{
SpringEntityListeners annotation = (SpringEntityListeners) entity.getJavaType().getAnnotation(SpringEntityListeners.class);
for (Class listenerClass : annotation.value())
{
Map<String, DescriptorEventListener> map = applicationContext.getBeansOfType(listenerClass);
for (DescriptorEventListener listenerBean : map.values())
{
ClassDescriptor classDescriptor = session.getClassDescriptor(entity.getJavaType());
if (null != classDescriptor)
{
classDescriptor.getEventManager().addListener(listenerBean);
}
}
}
}
}
}
}
因此,现在我可以使用所需的任何侦听器将@SpringEntityListeners({ApprovalEntityListener.class})添加到所需的任何实体,这些侦听器可以是spring bean!
如果有帮助,这里是注释:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SpringEntityListeners
{
Class<?>[] value();
}
标签:jpa-2-0,eclipselink,spring 来源: https://codeday.me/bug/20191029/1958626.html