好的,我在用户和帐户之间有一对多的关系,帐户和account_details之间有一对一的关系。如果在account_details级别插入用户期间发生错误,则不会插入帐户,但会为用户执行记录。同样,如果错误发生在帐户级别,则会插入用户帐户。 EntityManager应该处理事务的回滚,但事实并非如此。 奇怪的是,当我更新用户帐户并向其添加帐户时,添加帐户级别的失败会回滚对用户模型的任何更新。
持久性xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
version="1.0">
<persistence-unit name="userPersistenceUnit" transaction-type="RESOURCE_LOCAL" >
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.urbanbuz.model.User</class>
<class>com.urbanbuz.model.Account</class>
<class>com.urbanbuz.model.AccountDetails</class>
</persistence-unit>
</persistence>
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;
}
// summary of method, much code was omitted
public boolean addUser(User user) {
// add new user and user accounts
Set<Account> accounts = new HashSet<Account>();
Account a = new Account();
a.setUser(user);
AccountDetails ad = new AccountDetails();
ad.setAccount(a);
a.setAccountDetails(ad);
accounts.add(a);
user.setAccount(accounts);
try {
getUserDao().insert(user);
}
catch(Exception e) {
}
}
}
关系定义如下:
在用户模型级别:
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="user")
private Set<Account> accounts;
在帐户模型级别:
@ManyToOne
@JoinColumn(name = "user_id")
public User getUser() {
return user;
}
答案 0 :(得分:1)
如果有人遇到同样的问题 - 我将表格类型从MyISAM改为支持实现回滚的InnoDB。
答案 1 :(得分:0)
我有类似的问题。在我的情况下,数据库设置为使用InnoDB,但是无论如何,Hibernate都使用MyISAM存储引擎创建了表。
下一行强制休眠使用InnoDB引擎,当然,这仅适用于新创建的表:
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL55Dialect
旧的可以使用例如sql脚本(alter table table_name ENGINE = InnoDB;).