Ok so I have a one to many relationship between user and account and one to one between account and account_details. When an error occurs during the insert of an user at the level of account_details the account does not get inserted but a record for user does. Similarly if the error occurs at the level of the account a user account is inserted. EntityManager is supposed to handle rollbacks for the transactions but it is not the case. Strangely when I update a user account and add accounts to it, a failure at the level of the added accounts rolls back any updates to the user model.
persistence 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);
}
}
Calling the method to insert 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) {
}
}
}
Relationship defined as follows:
at user model level:
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="user")
private Set<Account> accounts;
at account model level:
@ManyToOne
@JoinColumn(name = "user_id")
public User getUser() {
return user;
}
In case anyone faces the same problem - I changed the table type from MyISAM to InnoDB that supports the implemented rollback.