在jpa项目中使用dozer时遇到了一个非常奇怪的现象。 我有一个UserSupplier对象和一个Supplier对象。
UserSupplier:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "supplier_id", nullable = false)
private Supplier supplier;
在我的代码中,我首先查询UserSupplier列表,然后将其转换为SupplierList。
List<Supplier> supplierList = new ArrayList<>(usList.size());
usList.forEach(us -> supplierList.add(us.getSupplier()));
然后我将SupplierList转换为SupplierView List并将其返回给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;
答案 0 :(得分:1)
阅读推土机文档后,我发现了一些事情。尝试之后,我得到了另一个解决方案。 那就是在类路径中添加一个dozer.properties,里面的内容是
org.dozer.util.DozerProxyResolver=org.dozer.util.HibernateProxyResolver
更多细节请看 this
答案 1 :(得分:0)
这可能是因为JPA使用代理对象来延迟加载单个实体引用。代理对象实际上是实体类的子类。我猜这个推土机只能在给定对象的类中声明的字段上找到@Mapping
注释,而不能在父类中定义的字段上找到。 Dozer项目声明注释映射为experimental。因此,它可能不会很好地覆盖映射类层次结构。
我建议尝试通过其他方式(XML,推土机映射API)配置supplierId的映射,看看它是否有效。如果全部失败,您可以在Supplier
和SupplierView
之间编写自定义MapperAware转换器。您可以使用提供的映射器将源对象映射到目标对象,并通过将id
的值复制到supplierId
来确定它。