我正在使用Spring事务,因此当POJO到DTO转换时,该事务仍然处于活动状态。
我想防止Dozer触发延迟加载,以使隐藏的sql查询永远不会发生:所有获取都必须通过HQL显式完成(以获得对性能的最佳控制)。
这是一个好习惯吗(我在任何地方都找不到它的记载)?
如何安全地做?
我在DTO转换之前尝试了这个:
PlatformTransactionManager tm = (PlatformTransactionManager) SingletonFactoryProvider.getSingletonFactory().getSingleton("transactionManager");
tm.commit(tm.getTransaction(new DefaultTransactionDefinition()));
我不知道事务会发生什么,但是Hibernate会话不会关闭,并且仍然会发生延迟加载。
我尝试了这个:
SessionFactory sf = (SessionFactory) SingletonFactoryProvider.getSingletonFactory().getSingleton("sessionFactory");
sf.getCurrentSession().clear();
sf.getCurrentSession().close();
而且它可以防止延迟加载,但是在直接在应用程序层(在我的项目中称为“ facade”)中操纵会话是否是一种好习惯?我应该担心哪些副作用?(我已经看到涉及POJO-> DTO转换的测试无法再通过AbstractTransactionnalDatasource Spring测试类启动,因为此类试图触发不再与活动会话链接的事务的回滚)。
我还尝试将传播设置为NOT_SUPPORTED或REQUIRES_NEW,但它会重用当前的Hibernate会话,并且不会阻止延迟加载。
我发现管理此问题的唯一通用解决方案(在研究了定制转换器,事件监听器和代理解析器之后)是实现定制字段映射器。我在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注入自定义字段映射器:
<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时找不到任何示例。