繁体   English   中英

Spring Data更新多对一属性

[英]Spring Data Update Many To One Property

我在Spring Data JPA中保存多对一字段时遇到问题。 如下所述,考虑实体用户和组:

    @Entity
    @Table(name = "Users")
    public class User {
        @Basic(optional = false)
        @Column(name = "username")
        private String username;

        @JoinColumn(name = "group_id", referencedColumnName = "id")
        @ManyToOne
        private Group group;
    }

    @Entity
    @Table(name = "groups")
    public class Group {
       @Basic(optional = false)
       @Column(name = "name")
       private String name;

       @OneToMany(mappedBy = "group",cascade=CascadeType.PERSIST)
       private Collection<User> userCollection;
    }

当我想更新用户实体并使用CrudRepository保存方法更改其组时,发生以下异常: org.hibernate.HibernateException:Group实例的标识符从2更改为1,这表明spring数据想要在编辑它的id字段时不是corrent, 我想更改它的引用,而不是其id

对于Update,我以DTO形式获取视图数据,然后使用Dozer Mapper将dto对象转换为实体对象,如下所述:

DozerBeanMapper mapper = new DozerBeanMapper();
// get user by id from database for editing
User user = this.userService.findByIdAndDeletedFalse(form.getId());
// merge view data and entity data using Dozer
mapper.map(form, user);
// save User entity
this.userService.save(user);

userService是仅调用crudRepository保存方法的bean。

有什么办法吗?

谢谢

发生此错误是因为您试图更改跟踪实体的id ,这在JPA中是不允许的。 您需要获取对新Group的引用,并将其分配给User.group

简而言之,代替此:

user.getGroup().setId(newId);

尝试这个:

user.setGroup(entityManager.getReference(Group.class, newId)); 

我认为您应该告诉Dozer使用以下xml排除group字段。

<field-exclude> 
  <a>group</a> 
</field-exclude>   

并手动设置group

mapper.map(form, user);
user.setGroup(this.groupService.finfById(form.group.getId()));
// save User entity
this.userService.save(user);

如果您不想在控制器中映射组。 您可以使用DozerConverter类,在其中可以获取group对象并在此处进行设置。

<mapping>
  <class-a>org.mypackage.Form</class-a>
  <class-b>org.mypackage.User</class-b>    
  <field custom-converter-id="org.mypackage.UserGroupCustomConverter">
    <a>groupId</a>
    <b>group</b>
  </field>
</mapping>  

public class UserGroupCustomConverter extends DozerConverter<Form, User> {

  public NewDozerConverter() {
    super(Form.class, User.class);
  }

  public Boolean convertTo(Form form, User user) {
     user.setGroup(this.groupService.finfById(form.group.getId()));
  }
}

这是因为您正在使用临时组。 您需要获取您的组,然后将该组分配给您的用户对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM