Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dao/hibernate/McUsrAttemptDAO.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dao/hibernate/McUsrAttemptDAO.java,v diff -u -r1.29 -r1.30 --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dao/hibernate/McUsrAttemptDAO.java 5 Sep 2013 17:35:12 -0000 1.29 +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dao/hibernate/McUsrAttemptDAO.java 23 Oct 2013 21:28:14 -0000 1.30 @@ -66,7 +66,7 @@ @Override public void saveMcUsrAttempt(McUsrAttempt mcUsrAttempt) { - this.getHibernateTemplate().save(mcUsrAttempt); + this.getHibernateTemplate().saveOrUpdate(mcUsrAttempt); } @Override Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/McLearningAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/McLearningAction.java,v diff -u -r1.78 -r1.79 --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/McLearningAction.java 12 Aug 2013 16:29:02 -0000 1.78 +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/McLearningAction.java 23 Oct 2013 21:28:14 -0000 1.79 @@ -29,6 +29,7 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.regex.Pattern; import javax.servlet.ServletContext; import javax.servlet.ServletException; @@ -64,7 +65,10 @@ import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; import org.lamsfoundation.lams.web.util.SessionMap; +import org.springframework.dao.DataIntegrityViolationException; +import com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException; + /** * @author Ozgur Demirtas */ @@ -326,7 +330,7 @@ mcGeneralLearnerFlowDTO.setUserOverPassMark(new Boolean(passed).toString()); mcGeneralLearnerFlowDTO.setPassMarkApplicable(new Boolean(mcContent.getPassMark() != null).toString()); - mcService.saveUserAttempt(mcQueUsr, selectedQuestionAndCandidateAnswersDTO); + McLearningAction.saveUserAttempt(mcQueUsr, selectedQuestionAndCandidateAnswersDTO); Integer numberOfAttempts = mcQueUsr.getNumberOfAttempts() + 1; mcQueUsr.setNumberOfAttempts(numberOfAttempts); @@ -393,7 +397,7 @@ //save user attempt List selectedQuestionAndCandidateAnswersDTO = buildSelectedQuestionAndCandidateAnswersDTO( learnerInput, new McTempDataHolderDTO(), mcContent); - mcService.saveUserAttempt(user, selectedQuestionAndCandidateAnswersDTO); + McLearningAction.saveUserAttempt(user, selectedQuestionAndCandidateAnswersDTO); McQueUsr mcQueUsr = getCurrentUser(toolSessionID); List learnerAnswersDTOList = mcService.buildLearnerAnswersDTOList(mcContent, mcQueUsr); @@ -725,11 +729,36 @@ List selectedQuestionAndCandidateAnswersDTO = buildSelectedQuestionAndCandidateAnswersDTO( learnerInput, new McTempDataHolderDTO(), mcContent); - mcService.saveUserAttempt(user, selectedQuestionAndCandidateAnswersDTO); + McLearningAction.saveUserAttempt(user, selectedQuestionAndCandidateAnswersDTO); return null; } + /** + * Makes a call to mcService.saveUserAttempt(). This method is designed purely for exception handling purposes. It + * needs to be performed inside Action class as otherwise Hibernate tries to flush the session which leads to another exception. + */ + private static void saveUserAttempt(McQueUsr user, List selectedQuestionAndCandidateAnswersDTO) { + try { + mcService.saveUserAttempt(user, selectedQuestionAndCandidateAnswersDTO); + + } catch (DataIntegrityViolationException e) { + + // log DB exceptions occurred due to creating non-unique McUsrAttempt. And propagate all the other exceptions + if (e.getRootCause() instanceof MySQLIntegrityConstraintViolationException) { + String rootCauseMessage = e.getRootCause().getMessage(); + + Pattern pattern = Pattern.compile("Duplicate entry.*attempt_unique_index"); + if ((rootCauseMessage != null) && pattern.matcher(rootCauseMessage).find()) { + logger.error("Prevented creation of McUsrAttempt which was not unique for user and question: " + rootCauseMessage); + return; + } + } + + throw e; + } + } + private static List parseLearnerAnswers(McLearningForm mcLearningForm, HttpServletRequest request) { String httpSessionID = mcLearningForm.getHttpSessionID(); SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(httpSessionID);