【发布时间】:2011-02-24 01:39:49
【问题描述】:
我在相对简单的用例上发现了非常奇怪的行为,可能由于对spring@Transactional性质的了解不深,我无法理解,但这很有趣。
我有一个简单的用户 dao,它扩展了 spring JpaDaoSupport 类并包含标准保存方法:
@Transactional
public User save(User user) {
getJpaTemplate().persist(user);
return user;
}
如果在我向同一个类添加新方法之前工作正常:用户 getSuperUser(),此方法应返回 isAdmin == true 的用户,如果 db 中没有超级用户,则方法应创建一个。原来是这样的:
public User createSuperUser() {
User admin = null;
try {
admin = (User) getJpaTemplate().execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
return em.createQuery("select u from UserImpl u where u.admin = true").getSingleResult();
}
});
} catch (EmptyResultDataAccessException ex) {
User admin = new User('login', 'password');
admin.setAdmin(true);
save(admin); // THIS IS THE POINT WHERE STRANGE THING COMING OUT
}
return admin;
}
正如你所看到的代码很奇怪,当我发现在调用 save(admin) 方法时没有创建和提交事务并且尽管@Transactional 注释没有实际创建新用户时,我感到非常困惑。
结果我们遇到的情况是:当 save() 方法从 UserDAO 类外部调用时 - @Transactional 注释计数并且用户成功创建,但如果 save() 从同一个 dao 类的其他方法内部调用 - @Transactional 注释忽略。
这里我是如何更改 save() 方法以强制它始终创建事务。
public User save(User user) {
getJpaTemplate().execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
em.getTransaction().begin();
em.persist(user);
em.getTransaction().commit();
return null;
}
});
return user;
}
如您所见,我手动调用了开始和提交。有什么想法吗?
【问题讨论】:
标签: java hibernate spring jpa aop