java – 保存后刷新并获取实体(JPA / Spring Data / Hibernate)
我有这两个简单的实体Something and Property.
Something实体与Property具有多对一关系,因此当我创建一个新的Something行时,我会分配一个现有的Property. 东西: @Entity @Table(name = "something") public class Something implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "name") private String name; @Column(name = "owner") private String owner; @ManyToOne private Property property; // getters and setters @Override public String toString() { return "Something{" + "id=" + getId() + ",name='" + getName() + "'" + ",owner='" + getOwner() + "'" + ",property=" + getProperty() + "}"; } 属性: @Entity @Table(name = "property") public class Property implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "shape") private String shape; @Column(name = "color") private String color; @Column(name = "dimension") private Integer dimension; // getters and setters @Override public String toString() { return "Property{" + "id=" + getId() + ",shape='" + getShape() + "'" + ",color='" + getColor() + "'" + ",dimension='" + getDimension() + "'" + "}"; } } 这是SomethingRepository(Spring): @SuppressWarnings("unused") @Repository public interface SomethingRepository extends JpaRepository<Something,Long> { } 通过REST控制器和JSON,我想创建一个新的东西: @RestController @RequestMapping("/api") public class SomethingResource { private final SomethingRepository somethingRepository; public SomethingResource(SomethingRepository somethingRepository) { this.somethingRepository = somethingRepository; } @PostMapping("/somethings") public Something createSomething(@RequestBody Something something) throws URISyntaxException { Something result = somethingRepository.save(something); return result; } } 这是输入中的JSON(属性id 1是数据库中的现有行): { "name": "MyName","owner": "MySelf","property": { "id": 1 } } 问题是:在方法.save(something)之后,变量result包含持久化实体,但没有field属性字段,验证(它们为null): 输出JSON: { "id": 1,"name": "MyName","property": { "id": 1,"shape": null,"color": null,"dimension": null } } 我希望在保存操作后验证/返回它们. 要解决这个问题,我必须在REST控制器中注入/声明EntityManager,并调用方法EntityManager.refresh(something)(或者我必须调用.findOne(something.getId())方法来获得完整的持久化实体): @RestController @RequestMapping("/api") @Transactional public class SomethingResource { private final SomethingRepository somethingRepository; private final EntityManager em; public SomethingResource(SomethingRepository somethingRepository,EntityManager em) { this.somethingRepository = somethingRepository; this.em = em; } @PostMapping("/somethings") public Something createSomething(@RequestBody Something something) throws URISyntaxException { Something result = somethingRepository.save(something); em.refresh(result); return result; } } 通过这种解决方法,我得到了预期的保存entith(使用正确的JSON): { "id": 4,"shape": "Rectangle","color": "Red","dimension": 50 } } 是否有自动方法/注释,使用JPA或Spring或Hibernate,以获得“完整”持久化实体? 我想避免在每个REST或Service类中声明EntityManager,或者我希望每次我想要新刷新的持久化实体时都避免调用.findOne(Long)方法. 非常感谢, 解决方法
这还不够:
Something result = somethingRepository.save(something); 您需要手动合并传入的实体: Something dbSomething = somethingRepository.findOne( Something.class,something.getId() ); dbSomething.setName(something.getName()); dbSomething.setOwner(something.getOwner()); somethingRepository.save(dbSomething); 由于属性属性使用默认值 但是,从REST控制器调用存储库两次是很奇怪的.你应该有一个服务层来完成@Transactional服务方法中的所有操作.这样,您不需要重新保存实体,因为它已经被管理. @Transactional public Something mergeSomething(Something something) { Something dbSomething = somethingRepository.findOne( Something.class,something.getId() ); dbSomething.setName(something.getName()); dbSomething.setOwner(something.getOwner()); return dbSomething; } 现在,您需要仔细合并您发送的每个属性.在您的情况下,如果您为属性发送null,您应该决定是否应该取消@ManyToOne引用.因此,它取决于您当前的应用程序业务逻辑要求. 更新 如果您确定始终发送回先前提取的同一实体,则可以使用合并. em.refresh(result); 但是您的属性属性只是一个id,而不是一个实际的子实体,因此您必须自己在Service层中解决它. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |