【问题标题】:How to make managed entities context aware?如何使托管实体上下文感知?
【发布时间】:2013-01-04 15:52:46
【问题描述】:

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

这个 REST 服务的客户端存根是一个注册的 Spring 服务

我想将那些外部对象的负载包装在休眠负载的过程中。这样,我可以确定我的对象在加载后始终有效,即使我通过复杂的 HQL 查询获取这些对象也是如此。

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

我尝试了以下方法:

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

目前,我正在使用一个肮脏的解决方法:一个 ApplicationHolder Spring 服务,它提供一个静态 getter,让 Spring 世界之外的对象可以访问它。

对于如何使休眠或持久 bean 上下文感知,您有什么最佳实践吗?

THks

编辑

在我的 DAO 中执行此操作是我的第一种方法,但实际上我有许多需要获取的子对象,如下所示:

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

我希望我的 LocalObject 具有一致、干净的负载。

这样,我可以在我的 DAO 中编写复杂的 HQL,而不必再为外部对象获取而烦恼。

【问题讨论】:

  • 我仍然认为 DAO 是要走的路。您可以向需要获取的外部实体添加自定义注释,DAO 将查找注释以查看要扫描的内容。 isagoksu.com/2009/development/java/…

标签: java spring hibernate


【解决方案1】:

如果您不想在道中这样做,那么也许这可以工作:

@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 一起使用,因为它们是直接实例化的(如 abandoned JIRA entry 中所述) .

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    解释我的评论的解决方案的速写:

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

    【讨论】:

    • 另外,它将逻辑排除在域对象之外!
    猜你喜欢
    • 1970-01-01
    • 2015-03-17
    • 2014-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多