在Service Class中调用时,服务类不更新数据库

时间:2016-03-26 03:51:38

标签: java spring spring-mvc spring-security spring-boot

我正在研究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方法也会正确返回值。

1 个答案:

答案 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()