我下面的結構建議在以上(http://viralpatel.net/blogs/spring3-mvc-hibernate-maven-tutorial-eclipse-example/)。我嘗試添加重複的條目,這導致了以下異常:
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/cct] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: Duplicate entry '[email protected]' for key 'PRIMARY'; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: Duplicate entry '[email protected]' for key 'PRIMARY'] with root cause
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '[email protected]' for key 'PRIMARY'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at << removed for readability>> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy26.addUser(Unknown Source)
at com.bilitutor.cct.control.HomeController.signup(HomeController.java:56)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
<< removed for readability>>
我有以下問題:
爲什麼例外是由控制器(
userService.addUser(user)
在com.bilitutor.cct.control.HomeController
)抓住,而不是由DAO(sessionFactory.getCurrentSession().save(user);
)然後冒泡到控制器?我知道我得到一個
org.springframework.dao.DataIntegrityViolationException
,因爲我使用的是@Repository
註釋,這可能是異常翻譯(糾正我,如果我錯了)。在那種情況下,當我發現異常時,如何找到它的錯誤代碼?作爲一種最佳實踐,哪一層(DAO,服務或控制器)是捕獲異常的最佳位置?
相關類:
控制器:
package com.bilitutor.cct.control;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.web.bind.annotation.ModelAttribute;
import com.bilitutor.cct.bean.*;
import com.bilitutor.cct.service.*;
/**
* Handles requests for the application home page.
*/
@Controller
public class HomeController {
@Autowired
UserService userService;
@ModelAttribute("user")
public User getUserObect() {
return new User();
}
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Landing page. Just return the login.jsp
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Model model) {
logger.info("home() called");
return "login";
}
/**
* Login. Either forward to the user's homepage or return back the error
*/
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login(Model model) {
logger.info("login() called");
return "login";
}
/**
* New User signup. If user already exists, send back the error, or send an email and forward to the email validation page
*/
@RequestMapping(value = "/signup", method = RequestMethod.POST)
public String signup(@ModelAttribute("user")User user, BindingResult result) {
logger.info("signup() : email="+user.getEmail()+" pass="+user.getPassword()+" accessCode="+user.getAccessCode());
userService.addUser(user);
return "login";
}
}
服務:
package com.bilitutor.cct.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.bilitutor.cct.dao.UserDAO;
import com.bilitutor.cct.bean.User;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDAO userDAO;
@Transactional
public void addUser(User user) {
userDAO.addUser(user);
}
@Transactional
public void removeUser(String email) {
userDAO.removeUser(email);
}
}
DAO:
package com.bilitutor.cct.dao;
import com.bilitutor.cct.bean.User;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class UserDAOImpl implements UserDAO {
@Autowired
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public void addUser(User user) {
sessionFactory.getCurrentSession().save(user);
}
public void removeUser(String email) {
User user = (User) sessionFactory.getCurrentSession().load(User.class, email);
if (user!=null) {
sessionFactory.getCurrentSession().delete(user);
}
}
}
其實,它是我的服務層是Transactional(我已經更新了上面的帖子)。在例外情況下,我想找出異常的原因(因此我的帖子中的問題2)併發回相應的消息(電子郵件已存在,密碼不能爲空等)。 – Amarsh