所以我在两个班级之间有一对多和多对一的关系。当我尝试更新实体时,更新父级并且子级抛出错误。在这种情况下,我希望回滚父更新,但事实并非如此。由于我有一对多的关系,父对象的更新应该插入一个子进程,但是当子进程发出错误时,父进程的更新是否应该回滚?如果它具有任何关系,则由于子/帐户实体的唯一约束而抛出了孩子的错误。
以下是我的两个模型:
/** User model **/
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", unique = true, nullable = false)
private int id;
@Column(name = "type")
private String type;
@Column(name = "username", nullable = false)
private String username;
...
// define one to many relation between User and Account
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "user_id")
private Set<Account> accounts;
public User() {
}
@PrePersist
void preInsert() throws ParseException {
...
}
// field getters and setters
...
// returns Account list associated with User
public Set<Account> getAccount() {
return accounts;
}
// set Account list associated with User
public void setAccount(Set<Account> accounts) {
this.accounts = accounts;
}
}
模型2:
/** Account model **/
@Entity
@Table(name = "account", uniqueConstraints =
@UniqueConstraint(columnNames = {"user_id", "entity_id", "branch_id", "type"}))
public class Account {
private int id;
@Column(name = "user_id", nullable = false)
private int user_id;
...
private User user;
// constructor
public Account() {
}
@PrePersist
void preInsert() throws ParseException {
...
}
// field getters and setters
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
...
// define many to one relation between Account and User
// get User associated with Account
@ManyToOne
@JoinColumn(name = "user_id", insertable = false, updatable = false)
public User getUser() {
return user;
}
// set User associated with Account
public void setUser(User user) {
this.user = user;
}
}
UserDAO的:
@Repository("userDao")
@Transactional(propagation = Propagation.REQUIRED)
public class UserDAO {
@PersistenceContext
private EntityManager entityManager;
public EntityManager getEntityManager() {
return entityManager;
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public void insert(User user) {
entityManager.persist(user);
}
public void update(User user) {
entityManager.merge(user);
}
....
}
用户服务(我呼叫更新的地方)
@Service
public class UserService {
private UserDAO userDAO;
public UserDAO getUserDao() {
return userDAO;
}
@Autowired
public void setUserDao(UserDAO userDAO) {
this.userDAO = userDAO;
}
public boolean addUser(SignupComponent signupComponent) {
....
else {
// case (4)
// get user object
User userObj = getUserDao().findUser(user.getPhone());
// update user object, adding account and account details
Set<Account> accounts = userObj.getAccount();
Account a = new Account();
a.setBranch_id(signupComponent.branch_id);
a.setEntity_id(signupComponent.entity_id);
if (signupComponent.type != -1) {
a.setType(signupComponent.type);
}
a.setUser(userObj);
userObj.setAccount(accounts);
userObj.setEmail(signupComponent.user.getEmail());
AccountDetails ad = new AccountDetails(); //never mind this line, i have another one to one relation with another entity
ad.setAccount(a);
a.setAccountDetails(ad);
accounts.add(a);
try {
getUserDao().update(userObj);
return true;
}
catch(Exception e) {
signupComponent.error = e.toString();
return false;
}
}
}
}
答案 0 :(得分:0)
您正在两侧定义JoinColumn。您需要在一侧定义。如何在一行中存储任意数量的外键?相反,它必须让集合中的实体表具有返回源实体表的外键。
试试这个:
public class User{
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL,mappedBy="user")
private Set<Account> accounts;
}
用户类
/** User model **/
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", unique = true, nullable = false)
private int id;
@Column(name = "type")
private String type;
@Column(name = "username", nullable = false)
private String username;
...
// FetchType should be Lazy to improve performance
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL,mappedBy="user")
private Set<Account> accounts;
//mappedBy says that this side is inverse side of relation and source is user which is mapped by user field name in Account class
public User() {
}
@PrePersist
void preInsert() throws ParseException {
...
}
// field getters and setters
...
// returns Account list associated with User
public Set<Account> getAccount() {
return accounts;
}
// set Account list associated with User
public void setAccount(Set<Account> accounts) {
this.accounts = accounts;
}
}
帐户类
/ **帐户模型** /
@Entity
@Table(name = "account", uniqueConstraints =
@UniqueConstraint(columnNames = {"user_id", "entity_id", "branch_id", "type"}))
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false)
private int id;
@Column(name = "user_id", nullable = false)
private int user_id;
...
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "user_id", insertable = false, updatable = false)
private User user;
// constructor
public Account() {
}
@PrePersist
void preInsert() throws ParseException {
...
}
// field getters and setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
...
// define many to one relation between Account and User
// get User associated with Account
public User getUser() {
return user;
}
// set User associated with Account
public void setUser(User user) {
this.user = user;
}
}
现在看,当您保存用户时,将不会更新帐户类,因为用户处于反面。但是当你保存Account类时,账户表中存在的user_id将会更新,因为它是关系的源端。