如何使托管实体上下文感知?

时间:2013-01-04 15:52:46

标签: java spring hibernate

我有一个使用 hibernate / JPA 进行持久化的应用程序。它使用 Spring 一些持久Bean依赖于我从 REST服务检索的外部对象

此REST服务的客户端存根是已注册的Spring服务

我想在hibernate加载过程中包装那些外部对象的负载。这样,我确信我的对象在加载后总是有效,即使我通过复杂的HQL查询获取这些对象。

问题是,无论我使用什么方法,我都很难在持久化的bean中获得 Spring应用程序上下文(以及REST客户端)。

我尝试了以下内容:

  • 使用 UserType 通过其ID从REST获取我的对象:
    CustomUserType由Hibernate实例化,因此不会发生Spring注入。
  • 使用 @AfterLoad JPA注释:
    这个更糟糕,没有EntityManager,Session或Spring上下文
  • 用户 LifeCycle 界面,onLoad(Session s,Serializable id)方法:
    我可以在这里访问会话。但我不知道如何制作一个 ApplicationContext 的自定义会话。

目前,我正在使用一个肮脏的解决方法:一个 ApplicationHolder Spring服务,它为Spring wolrd中的对象提供静态getter,以便访问它。

关于如何使hibernate或持久bean上下文知道,你有什么最好的实践吗?

THKS

修改

在我的DAO中执行它是我的第一个方法,但实际上我有许多需要提取的子对象,如下所示:

LocalObject
* - localSubObject1
    - refToExternalObject ----------> externalObject1
* - localSubObject2 
    - refToExternalObject ----------> externalObject2
    - refToExternalObject ----------> externalObject3

我希望我的LocalObject能够保持一致,干净的负载。

通过这种方式,我可以在DAO中编写复杂的HQL,而不用再担心外部对象的获取了。

2 个答案:

答案 0 :(得分:1)

解释我的评论的解决方案的快速草图:

@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;
    }
}

答案 1 :(得分:1)

如果你不想在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 EventListeners(在配置中或通过Integrators)的替代方法不能与Spring bean一起使用,因为它们是直接实例化的(如此{{ 3}})。

希望有所帮助。