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