【发布时间】:2025-11-22 09:55:02
【问题描述】:
我有 2 张桌子:User 和 Loan。用户有 3 个字段:id (PK)、first_name 和 last_name。 Loan 表有字段 user_id 是 User 表的外键:
我的应用程序的逻辑:当我创建新的Loan 对象并在那里设置相应的user 时,它应该为唯一用户创建一个新对象,或者将user 的id 设置为user_id现有用户。
为此,我的数据库在first_name、last_name 上有一个唯一索引。
Loan 类使用User 与@ManyToOne 关系:
public class Loan {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "user_id")
private User user;
... methods ...
当我添加新用户时,一切都很好,它通过新的 PK 持续存在于数据库中。但是当我尝试添加一个现有的时,我得到了一个例外:
javax.servlet.ServletException: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'FIRST_LAST_NAME' defined on 'USER'.
Error Code: 20000
当我再次输入@ManyToOne(cascade = CascadeType.MERGE) 时,我只能输入现有用户,因为只有我传递了一个未保存在数据库中的新用户,所以我遇到了一个异常:
javax.servlet.ServletException: org.springframework.dao.InvalidDataAccessApiUsageException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: User{id=null, firstName='a', lastName='a'}.;
@ManyToOne(cascade = CascadeType.ALL) 效果不佳。
更新
插入新Loan的代码是:
user = userService.findByName(firstName, lastName);
if (user == null) {
user = new User(firstName, lastName);
}
loan.setUser(user);
loanService.save(loan);
findByName() 和 save() 方法是:
private EntityManager em;
public User findByName(String firstName, String lastName) {
TypedQuery<User> query = em.createQuery(
"SELECT u FROM User u WHERE u.firstName = :firstName " +
"AND u.lastName = :lastName", User.class)
.setParameter("firstName", firstName).setParameter("lastName", lastName);
List<User> users = query.getResultList();
if (!users.isEmpty()) {
return users.iterator().next();
} else {
return null;
}
}
public void save(User user) {
if (user.getId() == null) {
em.persist(user);
} else {
em.merge(user);
}
}
【问题讨论】:
-
向我们展示您的插入代码。
-
请同时发布用户类的代码。
-
我更新了问题,谢谢
-
我不太确定问题或您在做什么,因为您的“储蓄”是为用户而不是贷款。
-
使用 Cascade.All 时出现什么错误,什么时候出现异常?
标签: java jpa persistence eclipselink