gpt4 book ai didi

java - 防止 Dozer 触发 Hibernate 延迟加载

转载 作者:IT老高 更新时间:2023-10-28 13:52:24 25 4
gpt4 key购买 nike

我正在使用 Spring 事务,因此当 POJO 到 DTO 转换发生时,事务仍然处于 Activity 状态。

我想防止 Dozer 触发延迟加载,这样隐藏的 sql 查询就不会发生:所有的提取都必须通过 HQL 显式完成(以获得对性能的最佳控制)。

  1. 这是一个好习惯吗(我在任何地方都找不到它的文档)?

  2. 如何安全操作?

我在 DTO 转换之前尝试过这个:

PlatformTransactionManager tm = (PlatformTransactionManager) SingletonFactoryProvider.getSingletonFactory().getSingleton("transactionManager");
tm.commit(tm.getTransaction(new DefaultTransactionDefinition()));

我不知道事务发生了什么,但是 Hibernate session 没有关闭,并且仍然发生延迟加载。

我试过这个:

SessionFactory sf = (SessionFactory) SingletonFactoryProvider.getSingletonFactory().getSingleton("sessionFactory");
sf.getCurrentSession().clear();
sf.getCurrentSession().close();

它可以防止延迟加载,但是直接在应用层(在我的项目中称为“外观”)中操作 session 是一种好习惯吗?我应该害怕哪些负面影响? (我已经看到涉及 POJO -> DTO 转换的测试不能再通过 AbstractTransactionnalDatasource Spring 测试类启动,因为这些类试图触发不再与 Activity session 链接的事务的回滚)。

我也尝试将传播设置为 NOT_SUPPORTED 或 REQUIRES_NEW,但它会重用当前的 Hibernate session ,并且不会阻止延迟加载。

最佳答案

我发现用于管理此问题的唯一通用解决方案(在查看自定义转换器、事件监听器和代理解析器之后)是实现自定义字段映射器。我发现这个功能隐藏在 Dozer API 中(我不相信它记录在用户指南中)。

一个简单的例子如下;

public class MyCustomFieldMapper implements CustomFieldMapper 
{
public boolean mapField(Object source, Object destination, Object sourceFieldValue, ClassMap classMap, FieldMap fieldMapping)
{
// Check if field is a Hibernate collection proxy
if (!(sourceFieldValue instanceof AbstractPersistentCollection)) {
// Allow dozer to map as normal
return false;
}

// Check if field is already initialized
if (((AbstractPersistentCollection) sourceFieldValue).wasInitialized()) {
// Allow dozer to map as normal
return false;
}

// Set destination to null, and tell dozer that the field is mapped
destination = null;
return true;
}
}

这会将任何未初始化的 PersistentSet 对象返回为 null。我这样做是为了当它们被传递给客户端时,我可以区分 NULL(未加载)集合和空集合。这允许我在客户端中定义通用行为以使用预加载的集合,或者进行另一个服务调用来检索集合(如果需要)。此外,如果您决定在服务层中急切地加载任何集合,那么它们将照常映射。

我使用 spring 注入(inject)自定义字段映射器:

<bean id="dozerMapper" class="org.dozer.DozerBeanMapper" lazy-init="false">
<property name="mappingFiles">
...
</property>
<property name="customFieldMapper" ref="dozerCustomFieldMapper" />
</bean>
<bean id="dozerCustomFieldMapper" class="my.project.MyCustomFieldMapper" />

我希望这可以帮助任何寻找解决方案的人,因为我在搜索 Internet 时没有找到任何示例。

关于java - 防止 Dozer 触发 Hibernate 延迟加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5552379/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com