Java Spring数据更新多对一属性
我在SpringDataJPA中保存多对一字段时遇到问题。 考虑实体用户和组,如下面简短描述的:Java Spring数据更新多对一属性,java,spring,hibernate,spring-mvc,jpa,Java,Spring,Hibernate,Spring Mvc,Jpa,我在SpringDataJPA中保存多对一字段时遇到问题。 考虑实体用户和组,如下面简短描述的: @Entity @Table(name = "Users") public class User { @Basic(optional = false) @Column(name = "username") private String username; @JoinColumn(name = "group_id
@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;
}
userService是一个只调用crudepository保存方法的bean
有解决办法吗
谢谢发生错误是因为您试图更改被跟踪实体的
id
,这在JPA中是不允许的。您需要获取对新的组的引用
,并将其分配给User.Group
简言之,与此相反:
user.getGroup().setId(newId);
试试这个:
user.setGroup(entityManager.getReference(Group.class, newId));
我认为您应该使用以下xml告诉
Dozer
排除group
字段
<field-exclude>
<a>group</a>
</field-exclude>
如果不想映射控制器中的组。您可以使用DozerConverter
类,在该类中可以获取组
对象并将其设置在那里
<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()));
}
}
org.mypackage.Form
org.mypackage.User
groupId
组
公共类UserGroupCustomConverter扩展了DozerConverter{
公共NewDozerConverter(){
super(Form.class、User.class);
}
公共布尔convertTo(表单,用户){
user.setGroup(this.groupService.finfbyd(form.group.getId());
}
}
这是因为您使用的是临时组。您需要获取您的组,然后将该组分配给您的用户对象。用户和组共享同一个表是否正确?请包括更新相关代码。亲爱的al27091,这是一个错误。您可以在更新用户。组的位置添加代码吗?错误消息听起来好像您正在为组
实体设置新的id
,而不是在用户
@crizzis中将User.Group.id更改为新的选定组id,然后调用save方法。如果组为空,这对我来说很好,但如果分配了一个组,并且我想更改它,我将面临该异常。感谢亲爱的@Crizis,我知道解决方案可行,但我不想在CONTORLER中提取组,我希望映射并传递视图数据以保存原因编辑用户组关系。根据这句话,你有什么建议吗。。。如果您没有实际加载新组,您怎么知道有这样一个id的组(仍然)存在?JPA怎么会知道?无论如何,它都必须通过数据库进行验证。我认为没有任何解决办法。请注意,EntityManager.getReference
不会加载组
实体的所有字段;它只会加载id(这是find
和getReference
之间的区别),而且,您不应该在控制器中加载组。您应该在您的服务方法中加载它,在Transaction视图的上下文中,我有一个下拉框包含所有组对象并传递给控制器,我有组对象及其id,甚至还有其他字段。如果您有对新组的引用,只需调用user.setGroup(newGroup)
谢谢@alayor先生,我不想在contorller中提取组,我想将视图数据映射并传递给save,以便编辑用户组关系。根据这句话,你有什么建议吗?
mapper.map(form, user);
user.setGroup(this.groupService.finfById(form.group.getId()));
// save User entity
this.userService.save(user);
<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()));
}
}