我有两个类,比如说
@Entity
public class Product{
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
private Provider provider;
//getter & setter
}
@Entity
public class Provider{
@Id
@GeneratedValue
private Long id;
private String name
//getter & setter
}
和相应的 DTO
public class ProductDTO{
private Long id;
private String name;
private ProviderDTO provider;
//getter & setter
}
为了简化 ProductDTO 和 product 具有相同的属性,我使用 dozer Mapping 将实体映射到 DTO 并将其发送到 View 。我有一个 View ,用户只能在 productDTO.name 中进行更改(这是一个更新),当他将更改发送到服务器时,我会做类似的事情
ProductServices.update(productDTO);
产品服务有
@Transactional
public void update(ProductDTO p){
Product p = DozerMapper.map(productDTO,ProductDTO.class);
productDao.update(p);
}
在 productDao 内部(我正在使用 spring,所以我正在注入(inject) sessionFactory 并在做,ProductServices 有 @Transactioanl 注释)
this.getCurrentSession().update(p);
所以 Hibernate 进行更新并设置 provider_id=null,我知道这是正确的,因为我发送到 ProductServices.update 的产品没有设置提供者,并且 Hibernate 将采用该产品没有提供者更新它在数据库中。
问题是我不确定如何解决这个问题,我是 hibernate 的新手,我发现的唯一解决方案是逐个字段执行选择和检查,看看有什么值发生了变化,但是如果,例如,我有一个更复杂的对象,我将不得不编写大量代码来检查每个字段。
任何人都知道更好的解决方案或我如何修改 mi 代码以正确处理这种情况?
我正在使用 Spring 3.1 和 hibernate 3.6。
提前致谢。
最佳答案
问题不是hibernate,“问题”是Dozer。
您需要先从数据库加载实体( hibernate )。然后让Dozer只修改你要修改的字段(而不是id),然后让Hibernate保存更新的实体。
我不详细了解推土机,因此将此代码作为原始草图:
@Transactional
public void update(ProductDTO dto){
Product p = productDao.loadById(dto.getId());
DozerMapper.map(dto,p); //you need to configure dozer to that it only map the fields you want to map.
productDao.update(p);
}
关于java - 使用 hibernate 从 DTO 更新实体会删除其他字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24163226/