我在弹簧hibernate
的上下文中使用CrudRepository
。它有一个save()
方法,基本上执行事务保存或合并,具体取决于对象。但这对我的问题的核心来说无关紧要。
当我想要修改来自@Entity
的外的@Transaction
对象时:再次获取实体会不会更好新交易中的byId
?或者我可以修改然后合并(保存)现有(分离)实体吗?
示例:
private CrudRepository<Entity> dao;
//find the db object
entity = dao.findOne(id);
//request a DTO via webservice using some of the entity params
dto = api.getDTO(entity.params);
//TODO: merge the response into the entity
updateEntity(entity, dto);
现在,api webservice调用无法在广泛的跨越事务中执行,因为它可能会长时间运行。因此,我在这里有一个分离的实体,我想合并。
我现在可以使用以下方法之一:
//now merge the dto
@Transactional
public void updateEntity(entity, dto) {
entity.param1 = dto.param1;
entity.param2 = dto.param2;
dao.save(entity);
}
或者我可以先获取实体:
@Transactional
public void updateEntity(id, dto) {
entity = dao.findOne(id);
entity.param1 = dto.param1;
entity.param2 = dto.param2;
//save(entity) can be neglected as the entity was fetched within the tx
}
两者都可行,但问题是:根据具体情况,哪种方法应该是首选方式?
我在哪里可以看到DIY Merge(第二种方法)的好处:如果我们首先在事务中获取实体,那么在合并期间,如果访问任何子对象,我们就无法获得LazyLoadingException
。
另外我认为em.merge(obj)
首先会触发&#34;按ID&#34;到数据库中找到应合并到的实体。如果我在这里更正确,我们也可以手动获取交易中的实体,因为我们没有获得性能增益或任何有利于合并的东西。正确的吗?