jpa项目中使用dozer的一个奇怪现象,为什么在lazy load对象中的Mapping注解不起作用?
A strange phenomenon when use dozer in jpa project,why Mapping annotation in lazy load object can't work?
我在jpa项目中使用dozer时遇到一个很奇怪的现象。
我有一个 UserSupplier 对象和一个 Supplier 对象。
UserSupplier:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "supplier_id", nullable = false)
private Supplier supplier;
在我的代码中,我首先查询 UserSupplier List,然后将其转换为 SupplierList。
List<Supplier> supplierList = new ArrayList<>(usList.size());
usList.forEach(us -> supplierList.add(us.getSupplier()));
然后我将 SupplierList 转换为 SupplierView List,然后 return 将其转换为 Caller。
BeanMapper.mapList(supplierList, SupplierView.class);
我的推土机在这些对象中配置如下
Supplier:
@Id
@GeneratedValue
@Mapping("supplierId")
private int id;
SupplierView:
private int supplierId;
很好笑,SupplierView中的supplierId一直为0(默认int值),但是其他字段可以转换成功,只有id字段失败。我不明白这是为什么,为什么只有id字段不能转换为supplierId,而其他字段可以?
针对以上问题,有以下解决方案
1. Change field name (supplierId to id):
Supplier:
// @Mapping("supplierId")
private int id;
SupplierView:
private int id;
but Caller(front-end) have to change code.
2. Change fetchType to eager:
UserSupplier:
@ManyToOne
private Supplier supplier;
这可能是因为 JPA 使用代理对象来延迟加载单个实体引用。代理对象实际上是实体 class 的子 class。我猜 dozer 只能在给定对象的 class 中声明的字段上找到 @Mapping
注释,而不能在父 classes 中定义的字段上找到。 Dozer 项目指出注释映射是 experimental。因此,它可能没有很好地涵盖映射 class 层次结构。
我建议尝试通过其他方式(XML、dozer 映射 API)配置 supplierId 的映射,看看它是否有效。如果都失败了,您可以在 Supplier
和 SupplierView
之间编写自定义 MapperAware 转换器。您将使用提供的映射器将源对象映射到目标对象,并通过将 id
的值复制到 supplierId
.
来完成它
阅读推土机文档后,我发现了一些东西。尝试之后,我得到了另一种解决方案。
即在classpath中加入一个dozer.properties,里面的内容为
org.dozer.util.DozerProxyResolver=org.dozer.util.HibernateProxyResolver
更多详情请看
http://dozer.sourceforge.net/documentation/proxyhandling.html
我在jpa项目中使用dozer时遇到一个很奇怪的现象。 我有一个 UserSupplier 对象和一个 Supplier 对象。
UserSupplier:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "supplier_id", nullable = false)
private Supplier supplier;
在我的代码中,我首先查询 UserSupplier List,然后将其转换为 SupplierList。
List<Supplier> supplierList = new ArrayList<>(usList.size());
usList.forEach(us -> supplierList.add(us.getSupplier()));
然后我将 SupplierList 转换为 SupplierView List,然后 return 将其转换为 Caller。
BeanMapper.mapList(supplierList, SupplierView.class);
我的推土机在这些对象中配置如下
Supplier:
@Id
@GeneratedValue
@Mapping("supplierId")
private int id;
SupplierView:
private int supplierId;
很好笑,SupplierView中的supplierId一直为0(默认int值),但是其他字段可以转换成功,只有id字段失败。我不明白这是为什么,为什么只有id字段不能转换为supplierId,而其他字段可以?
针对以上问题,有以下解决方案
1. Change field name (supplierId to id):
Supplier:
// @Mapping("supplierId")
private int id;
SupplierView:
private int id;
but Caller(front-end) have to change code.
2. Change fetchType to eager:
UserSupplier:
@ManyToOne
private Supplier supplier;
这可能是因为 JPA 使用代理对象来延迟加载单个实体引用。代理对象实际上是实体 class 的子 class。我猜 dozer 只能在给定对象的 class 中声明的字段上找到 @Mapping
注释,而不能在父 classes 中定义的字段上找到。 Dozer 项目指出注释映射是 experimental。因此,它可能没有很好地涵盖映射 class 层次结构。
我建议尝试通过其他方式(XML、dozer 映射 API)配置 supplierId 的映射,看看它是否有效。如果都失败了,您可以在 Supplier
和 SupplierView
之间编写自定义 MapperAware 转换器。您将使用提供的映射器将源对象映射到目标对象,并通过将 id
的值复制到 supplierId
.
阅读推土机文档后,我发现了一些东西。尝试之后,我得到了另一种解决方案。 即在classpath中加入一个dozer.properties,里面的内容为
org.dozer.util.DozerProxyResolver=org.dozer.util.HibernateProxyResolver
更多详情请看 http://dozer.sourceforge.net/documentation/proxyhandling.html