【发布时间】:2021-06-09 18:34:01
【问题描述】:
我正在开发一个使用 Spring MVC、JSP、Hibernate 和 MySQL 构建的简单应用程序。
我有两个实体:User 和 UserDetail。
用户
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "name")
@NotNull(message = "required field")
@Size(min = 3, message = "should contain at-least 3 characters")
private String name;
@Column(name = "salary")
@NotNull(message = "required field")
@Min(value = 0, message = "should be a valid positive number")
private int salary;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@Valid
private List<UserDetail> addressList;
...
}
用户详情
@Entity
@Table(name = "user_detail")
public class UserDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "address")
@NotNull(message = "required field")
@Size(min = 5, message = "should contain at-least 5 characters")
private String address;
@ManyToOne(cascade = {
CascadeType.DETACH, CascadeType.MERGE,
CascadeType.PERSIST, CascadeType.REFRESH}
)
@JoinColumn(name = "user_id")
private User user;
...
}
User 和 UserDetail 实体之间存在 one-to-many 关系 - 单个用户可以有多个地址。
前端有一个表单,其中包含以下字段:
- 姓名
- 工资
- 地址(可以是多个地址,用户可以通过按钮添加更多输入字段)
从前端提交表单后,我会验证表单数据,一旦确定表单数据有效,我就会调用将数据插入MySQL 数据库的方法。
问题
当表单仅提交一个地址时,数据正确保存在数据库中。
问题是表单提交时包含多个地址。例如,如果使用两个地址提交表单,则数据正确插入到user 表中,但在user_detail 表中,而不是插入两条记录,而是插入了 3 条记录。
以下是user_detail表数据不正确的截图:
在上面的截图中,id 为 1 的用户有两个地址,但插入了三行,中间一行与用户没有关联,即user_id 是null。
下图显示了hibernate在控制台记录的sql语句:
如果提交的表单数据中有3个地址,下面的截图显示了user_detail表中插入的数据:
“测试地址2”和“测试地址3”重复。
下图显示了hibernate在控制台记录的sql语句:
以下方法用于插入数据:
public static void saveUserData(User user) {
SessionFactory factory = new Configuration()
.configure("hibernate.cfg.xml")
.addAnnotatedClass(User.class)
.addAnnotatedClass(UserDetail.class)
.buildSessionFactory();
Session session = factory.getCurrentSession();
try {
session.beginTransaction();
session.save(user);
UserDetail userDetail;
for (int i = 0; i < user.getAddressList().size(); i++) {
userDetail = user.getAddressList().get(i);
userDetail.setUser(user);
session.save(userDetail);
// hibernate batch insert
// 10 --> hibernate's batch size
if (i % 10 == 0) {
session.flush();
session.clear();
}
}
session.getTransaction().commit();
} catch (HibernateException | ConstraintViolationException e) {
if (session.getTransaction() != null) {
session.getTransaction().rollback();
}
System.out.println(e.getLocalizedMessage());
}
finally {
session.close();
factory.close();
}
}
问题
为什么休眠会在user_detail 表中插入额外的记录?我该如何解决这个问题?
版本:
Spring (5.3.4)Hibernate (5.4.29.Final)
【问题讨论】:
标签: java mysql spring hibernate spring-mvc