Hibernate - 子级别的错误不会将父级插入回滚到数据库中

时间:2014-11-30 12:35:17

标签: java spring hibernate hibernate-mapping

好的,我在用户和帐户之间有一对多的关系,帐户和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;  
}  

2 个答案:

答案 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;).