Spring modelmapper映射延迟加载的实体



我使用modelmapper (http://modelmapper.org/)将具有延迟加载列表(通过hibernate)对象的实体映射到使用modelmapper.map()的DTO。

尽管实体的列表已被填充,但输出的dto作为列表具有空值。当我改变为急于加载一切工作正常,但我的查询太大,所以这不是一个选项。

有人知道modelmapper如何映射代理hibernate实体类吗?

这是我的父实体:

public class Category {
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "category")
@OrderBy("sortOrder")
private SortedSet<CategorySubarea> categorySubareas;
}

dto:

@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
public class CategoryDto {
private LinkedHashSet<@Valid CategorySubareaDto> categorySubareas;
}

我是这样使用映射器的(sourceCategory是实体,destinationCategory是dto):

modelMapper.map(sourceCategory, destinationCategory);

当然像这样的东西可以工作,但这是一个非常丑陋的解决方案:

sourceCategory.getCategorySubareas().forEach(subarea -> {
// do nothing here
});
modelMapper.map(sourceCategory, destinationCategory);

我知道用mapstruct处理lazy/dto的好方法。只需创建自定义上下文类

public class CycleAvoidingMappingContext {
private Map<Object, Object> knownInstances = new IdentityHashMap<Object, Object>();
PersistenceUtil persistenceUnitUtil = Persistence.getPersistenceUtil();
@SneakyThrows
@BeforeMapping
public <T> T getMappedInstance(Object source, @TargetType Class<T> targetType) {
if (source != null) {
for (PropertyDescriptor pd : Introspector.getBeanInfo(source.getClass()).getPropertyDescriptors()) {
if (pd.getWriteMethod() != null && pd.getReadMethod() != null && !"class".equals(pd.getName())) {
var vvalue = pd.getReadMethod().invoke(source);
if (vvalue == null) {
continue;
}
var classs = vvalue.getClass();
if (HibernateProxy.class.isAssignableFrom(classs)) {
try {
if (Hibernate.isInitialized(vvalue) == false) {
pd.getWriteMethod().invoke(source, null);
}
} catch (Exception e) {
}
}
}
}
}
return (T) knownInstances.get(source);
}
@BeforeMapping
public void storeMappedInstance(Object source, @MappingTarget Object target) {
knownInstances.put(source, target);
}
}

像这样使用:

CrmClientMapper.INSTANCE.getDto(client, new CycleAvoidingMappingContext());

它会跳过惰性字段,所以你不会得到惰性初始化异常和不必要的数据库查询。您可以使用实体图来指定要获取的关系。

最新更新