我正在研究Java Spring MVC项目。当Controller调用ServiceImpl类(updateAttempt())中的方法时,该类又调用DAOImpl类,更新发生,我在DB中看到更新的数据。
但是当loadUserByUserName(存在于ServiceImpl类中)在同一个ServiceImpl类中调用updateAttempt()方法时,它不会抛出任何错误或异常,但数据永远不会在DB中更新。
PersonController.java
@Controller
@SessionAttributes({ "mob_Number"})
public class PersonController implements Observer, InitializingBean{
private static final Logger logger = LoggerFactory.getLogger(PersonController.class);
private PersonService personService;
@Autowired(required=true)
@Qualifier(value="personService")
public void setPersonService(PersonService ps){
this.personService = ps;
}
public PersonController(PersonService personService){
this.personService = personService;
}
public PersonController(){
}
@RequestMapping(value="/submitVerificationCode",method = RequestMethod.POST, headers = "Accept=application/json")
@ResponseBody
public String submitVerificationCode(@RequestBody String json){
......
this.personService.update_User_Verification_AttemptCount(userVer.getMobile_Number(), no_Attempts);
//this call updates the data in DB
}
}
PersonServiceImpl.java
@Service
public class PersonServiceImpl implements PersonService, UserDetailsService {
private static final Logger logger = LoggerFactory.getLogger(PersonServiceImpl.class);
private PersonDAO personDAO;
private PersonService personService;
public void setPersonDAO(PersonDAO personDAO) {
this.personDAO = personDAO;
}
@Autowired
private Observer observe;
@Override
@Transactional
public void update_User_Verification_AttemptCount(String mobile_number, int count){
this.personDAO.update_User_Verification_AttemptCount(mobile_number, count);
}
@Override
@Transactional
public UserDetails loadUserByUsername(String mobile_Number)
throws UsernameNotFoundException {
this.update_User_Verification_AttemptCount(mobile_Number, no_Attempts); //but this call doesn't update the data in DB
this.getUserDetails() //but this call returns data from DB
}
PersonDAOImpl.java
@Repository
public class PersonDAOImpl implements PersonDAO {
private static final Logger logger = LoggerFactory.getLogger(PersonDAOImpl.class);
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sf){
this.sessionFactory = sf;
}
@Override
public void update_User_Verification_VerCode(String mob_number, String verCode, Timestamp currentTimestamp){
Session session = this.sessionFactory.getCurrentSession();
Query query = session.createQuery("update UserVerification set ver_Code=:verCode, sent_Time=:currentTimestamp where mobile_Number=:mob_Number");
query.setParameter("verCode", verCode);
query.setParameter("currentTimestamp", currentTimestamp);
query.setParameter("mob_Number", mob_number);
query.executeUpdate();
session.flush();
}
}
注意:当从loadUserByUsername调用get方法时,驻留在ServiceImpl(确实选择)中的get方法也会正确返回值。
答案 0 :(得分:1)
这是因为当您在同一服务中调用方法时,您的事务不会提交。
问题在于Spring通过将bean包装在代理中并向其添加行为来丰富bean的事务行为。但是,代理始终是在接口周围创建的,因此调用带有this
关键字的方法不会传播所需的行为。
一个正确的解决方案是重复dao调用,以避免调用相同的服务方法
@Transactional
public UserDetails loadUserByUsername(String mobile_Number)
throws UsernameNotFoundException {
this.personDAO.update_User_Verification_AttemptCount(mobile_number, count);
this.getUserDetails() //but this call returns data from DB
}
你可以做的另一件事(hacky事情)是,因为你已经personService
PersonServiceImpl
,所以首先要确保注入它,所以添加@Autowired
< / p>
@Autowired private PersonService personService;
并通过界面拨打电话,例如
personService.update_User_Verification_AttemptCount(mobile_Number, no_Attempts);
personService.getUserDetails()