您的位置:首页 > 编程语言 > Java开发

jpa+spring jdbc混合作战引发的缓存问题

2014-12-24 21:53 337 查看
在开发中,很可能会出现orm框架与jdbc混合使用.但这种混合要理解缓存机制,不然可能会出现混乱.

先看一下例子:

@Service
public class UserServiceImpl implements UserService{
@PersistenceContext
protected EntityManager entityManager;
@Resource
private JdbcTemplate jdbcTemplate;
@Override
@Transactional
public void signIn(String username, String password){
User user= entityManager.find(User.class,username);
long time1=System.currentTimeMillis();
user.setLastLoginTime(time1);
System.out.println("hibernateTemplate.update:"+time1);
entityManager.merge(user);
//entityManager.flush();
long time2=System.currentTimeMillis();
System.out.println("jdbcTemplate.update:"+time2);
jdbcTemplate.update("update user set lastLoginTime=? where username=?",time2,username);
}
}
此处先加载用户,使用jpa对用户修改再保存登录时间,然后又使用spring jdbc保存登录时间.但执行调用此方法后,保存的最终登录时间并不是jdbcTemplate去更改的,而是因为jpa的session在执行完方法前提交,并覆盖了jdbcTemplate的修改.jpa调用merge方法,因为缓存机制,并不会马上同步数据库.如果要即时同步数据库,可把上面的注释去掉,调用entityManager.flush()即可提交session.此时,jpa的同步数据库在先,jdbcTemplate修改在后.

虽然业务上不可能去保存两次时间,但类似这样的例子是存在的,比如使用spring jdbc修改登录时间,而jpa先从数据库加载数据出来,并不想修改登录时间,而修改其它字段数据,最终造成spring jdbc修改无效.防止这种在一个方法混合使用几种数据访问技术引起的问题,解决的方法:

1.像上面一样,适当使用entityManager.flush().

2.只用spring jdbc查数据,而可使用jpa读写数据.

对于hibernate+spring jdbc也会出现这种问题
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring