Java 如何使用ModelMapper基于源值而不是其类型创建条件转换器?

Java 如何使用ModelMapper基于源值而不是其类型创建条件转换器?,java,mapping,modelmapper,Java,Mapping,Modelmapper,我正在尝试使用将实体映射到DTO。当@JoinColumn未加载(延迟加载)时就会出现问题。ModelMapper尝试访问延迟加载实体的属性,然后引发LazyInitializationException 我已经有了解决这个问题的策略,但是我找不到一个ModelMapper特性来满足我的需要 以下是我需要做的: 对于每个未加载的实体,我将使用我的工厂创建一个新的目标对象。如果加载了对象,则必须应用默认映射 以下示例是一个ModelMapper功能,如果它不提供源(仅提供源类型),它将完全符合我的

我正在尝试使用将实体映射到DTO。当@JoinColumn未加载(延迟加载)时就会出现问题。ModelMapper尝试访问延迟加载实体的属性,然后引发LazyInitializationException

我已经有了解决这个问题的策略,但是我找不到一个ModelMapper特性来满足我的需要

以下是我需要做的: 对于每个未加载的实体,我将使用我的工厂创建一个新的目标对象。如果加载了对象,则必须应用默认映射

以下示例是一个ModelMapper功能,如果它不提供源(仅提供源类型),它将完全符合我的需要:

公共静态类MyConverter实现ConditionalConverter{
私人实体管理者;
公共MyConverter(实体管理器em){
this.em=em;
}
@凌驾
公共匹配结果匹配(类sourceType、类destinationType){
Object source=null;//我需要源而不是它的类型。
PersistenceUnitUtil PersistenceUnitUtil=em.getEntityManagerFactory().getPersistenceUnitUtil();
返回persistenceUnitUtil.isLoaded(源)?MatchResult.NONE:MatchResult.FULL;
}
@凌驾
公共对象转换(映射上下文){
返回LazyEntityProxyFactory.factory(context.getSource(),context.getDestinationType());//创建目标对象
}
}
你们有没有任何ModelMapper功能,它提供了我所需要的。或者是黑客


*Obs:我研究了ModelMapper的代码,注意到当调用when时,上下文已经存在,因此它拥有源代码。如果ModelMapper还有一个ConditionalContextConverter接口,它在match方法中传递上下文,会怎么样?只是个主意。

我刚刚找到了我需要的东西!秘密在于检查父实体的属性。之后,我可以利用默认映射,如果需要,还可以使用自己的工厂

这是我的条件转换器:

public static class MyConverter implements ConditionalConverter<Object, Object> {

    private EntityManager em;

    public MyConverter(EntityManager em) {
        this.em = em;
    }

    @Override
    public MatchResult match(Class<?> sourceType, Class<?> destinationType) {
        return MatchResult.FULL;
    }

    @Override
    public Object convert(MappingContext<Object, Object> context) {
        Object source = context.getSource();
        Object destination = context.getMappingEngine().createDestination(context);

        try {
            Field[] sourceFields = context.getSourceType().getDeclaredFields();
            Field[] destinationFields = context.getDestinationType().getDeclaredFields();
            for (Field sourceField : sourceFields) {
                sourceField.setAccessible(true);
                for (Field destinationField : destinationFields) {
                    destinationField.setAccessible(true);
                    if (sourceField.getName().equals(destinationField.getName())) {
                        Object sourceFieldValue = sourceField.get(source);

                        PersistenceUnitUtil persistenceUnitUtil = em.getEntityManagerFactory().getPersistenceUnitUtil();
                        if (persistenceUnitUtil.isLoaded(sourceFieldValue)) {
                            MappingContext<?, ?> myContext = context.create(sourceFieldValue, destinationField.getType());
                            Object destinationValue = context.getMappingEngine().map(myContext);
                            destinationField.set(destination, destinationValue);
                        } else {
                            // Here is your factory call;
                            destinationField.set(destination, SomeFactory.factory(sourceFieldValue, destinationField.getType()));
                        }
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return destination;
    }
}
公共静态类MyConverter实现ConditionalConverter{
私人实体管理者;
公共MyConverter(实体管理器em){
this.em=em;
}
@凌驾
公共匹配结果匹配(类sourceType、类destinationType){
返回MatchResult.FULL;
}
@凌驾
公共对象转换(映射上下文){
对象源=context.getSource();
对象目标=context.getMappingEngine().createDestination(上下文);
试一试{
Field[]sourceFields=context.getSourceType().getDeclaredFields();
字段[]destinationFields=context.getDestinationType().getDeclaredFields();
用于(字段源字段:源字段){
sourceField.setAccessible(true);
for(字段destinationField:destinationFields){
destinationField.setAccessible(true);
if(sourceField.getName().equals(destinationField.getName())){
对象sourceFieldValue=sourceField.get(source);
PersistenceUnitUtil PersistenceUnitUtil=em.getEntityManagerFactory().getPersistenceUnitUtil();
if(persistenceUnitUtil.isLoaded(sourceFieldValue)){
MappingContext myContext=context.create(sourceFieldValue,destinationField.getType());
Object destinationValue=context.getMappingEngine().map(myContext);
destinationField.set(destination,destinationValue);
}否则{
//这是你的工厂电话;
set(destination,SomeFactory.factory(sourceFieldValue,destinationField.getType());
}
打破
}
}
}
}捕获(例外e){
e、 printStackTrace();
}
返回目的地;
}
}
public static class MyConverter implements ConditionalConverter<Object, Object> {

    private EntityManager em;

    public MyConverter(EntityManager em) {
        this.em = em;
    }

    @Override
    public MatchResult match(Class<?> sourceType, Class<?> destinationType) {
        return MatchResult.FULL;
    }

    @Override
    public Object convert(MappingContext<Object, Object> context) {
        Object source = context.getSource();
        Object destination = context.getMappingEngine().createDestination(context);

        try {
            Field[] sourceFields = context.getSourceType().getDeclaredFields();
            Field[] destinationFields = context.getDestinationType().getDeclaredFields();
            for (Field sourceField : sourceFields) {
                sourceField.setAccessible(true);
                for (Field destinationField : destinationFields) {
                    destinationField.setAccessible(true);
                    if (sourceField.getName().equals(destinationField.getName())) {
                        Object sourceFieldValue = sourceField.get(source);

                        PersistenceUnitUtil persistenceUnitUtil = em.getEntityManagerFactory().getPersistenceUnitUtil();
                        if (persistenceUnitUtil.isLoaded(sourceFieldValue)) {
                            MappingContext<?, ?> myContext = context.create(sourceFieldValue, destinationField.getType());
                            Object destinationValue = context.getMappingEngine().map(myContext);
                            destinationField.set(destination, destinationValue);
                        } else {
                            // Here is your factory call;
                            destinationField.set(destination, SomeFactory.factory(sourceFieldValue, destinationField.getType()));
                        }
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return destination;
    }
}