Java 如何使托管实体具有上下文意识?
我有一个应用程序使用hibernate/JPA进行持久化。它使用弹簧Java 如何使托管实体具有上下文意识?,java,spring,hibernate,Java,Spring,Hibernate,我有一个应用程序使用hibernate/JPA进行持久化。它使用弹簧 一些持久化bean依赖于我从REST服务检索的外部对象。 此REST服务的客户端存根是注册的Spring服务 我想在hibernate加载过程中包装这些外部对象的加载。通过这种方式,我确信我的对象在加载后总是有效的,即使我通过复杂的HQL查询获得这些对象 问题是,无论我使用什么方法,我都很难在持久化bean中获得Spring应用程序上下文(以及REST客户端) 我尝试了以下方法: 使用UserType通过其ID从REST获取
一些持久化bean依赖于我从REST服务检索的外部对象。 此REST服务的客户端存根是注册的Spring服务 我想在hibernate加载过程中包装这些外部对象的加载。通过这种方式,我确信我的对象在加载后总是有效的,即使我通过复杂的HQL查询获得这些对象 问题是,无论我使用什么方法,我都很难在持久化bean中获得Spring应用程序上下文(以及REST客户端) 我尝试了以下方法:
- 使用UserType通过其ID从REST获取我的对象:
CustomUserType由Hibernate实例化,因此不会发生Spring注入 - 使用@AfterLoadJPA注释:
更糟糕的是,没有EntityManager、会话或Spring上下文可用 - 用户生命周期接口,onLoad(会话s,可序列化id)方法:
我可以在这里参加会议。但我不知道如何创建一个自定义会话,该会话将ApplicationContext感知
LocalObject
* - localSubObject1
- refToExternalObject ----------> externalObject1
* - localSubObject2
- refToExternalObject ----------> externalObject2
- refToExternalObject ----------> externalObject3
我希望本地对象具有一致、干净的加载
这样,我就可以在我的DAO中编写复杂的HQL,而不必再为获取外部对象而烦恼。一个解决方案的快速草图来解释我的评论:
@Component
public class HibernateDao {
@Resource
private SessionFactory sessionFactory;
@Resource
private RestClient restClient;
public LocalObject loadLocalObject(Serializable id) {
LocalObject localObject = sessionFactory.getCurrentSession().load(id);
ExternalObject externalObject = restClient.getExternalObject(id);
localObject.setVal(externalObject.getVal())
// ... more of this ...
return localObject;
}
}
如果您不想在Dao中执行此操作,那么这可能会起作用:
@Component
public class MyPostLoadEventListener implements PostLoadEventListener {
@Resource
private SessionFactoryImpl sessionFactoryImpl;
@Resource
private RestClient restClient;
@PostConstruct
public void installAsEventListener() {
sessionFactoryImpl.getServiceRegistry()
.getService(EventListenerRegistry.class)
.getEventListenerGroup(EventType.POST_LOAD)
.appendListener(this);
}
@Override
public void onPostLoad(PostLoadEvent event) {
if (event.getEntity() instanceof LocalObject) {
// fill with data from RestClient
}
}
}
这有点混乱,但不幸的是,注册Hibernate EventListener的替代方法(在配置中或通过)不能用于Springbean,因为它们是直接实例化的(如本文所述)
希望这会有所帮助。将Hibernate Dao作为一个bean(可能是注入SessionFactory等),并在返回它之前在Dao方法中完成实体初始化,这样会更干净。我仍然认为Dao是一种方式。您可以向需要获取的外部实体添加自定义注释,DAO将查找注释以查看要扫描的内容。另外,它将逻辑排除在域对象之外!