Spring JPA Hibernate:无需find操作获取已持久化的游离实体
我正在使用Spring、JPA、Hibernate。假设存在一个@ManyToMany关联关系,并且通过以下方式更新了关联关系的拥有方:
entity.getRelationshipOwners().addAll(_relatioshipOwners); for (RelationshipOwner relationshipOwner : _relatioshipOwners) { relationshipOwner.getEntities().add(entity); irelationshipOwnerRepository.save(relationshipOwner); }
现在,对象entity虽已持久化到数据库,但处于游离(detached)状态。我不想通过数据库的find操作获取该持久化实体(这会增加开销),请问是否存在无需查询数据库即可获取该持久化实体的方法?
有几种不用查数据库就能把游离态的entity转回持久态的方法:
使用EntityManager的merge()方法
调用entityManager.merge(entity),这个方法会把游离态实体的状态合并到当前持久化上下文里的对应实体,返回的就是处于持久态的对象。注意:merge()不会修改原来的游离态对象,后续操作要用它返回的新实例。使用EntityManager.getReference()获取代理
如果你知道entity的主键ID,可以调用entityManager.getReference(你的实体类.class, entity.getId())。这个方法不会立刻查询数据库,只会返回一个代理对象,只有当你访问代理的非主键属性时才会触发查询。如果只是需要持久态实体来维护关联关系,这个代理完全够用,不会产生额外开销。使用lock()方法重新关联持久化上下文
确认数据库中已存在该实体,且当前持久化上下文没有该实体的其他实例时,可以调用entityManager.lock(entity, LockModeType.NONE)。这个操作会把游离态实体重新绑定到持久化上下文,不会触发数据库查询。
另外,针对你当前的多对多关联更新逻辑,其实可以优化:既然entity是关联的拥有方,直接更新它的关联集合后调用entityRepository.save(entity)即可,Hibernate会自动处理中间表的关联关系,无需手动遍历非拥有方逐个保存,这样也能避免entity变成游离态的问题。
内容的提问来源于stack exchange,提问作者mammut

