为什么代码在Spring中验证之前插入数据

时间:2013-10-01 10:17:10

标签: java spring hibernate spring-mvc spring-validator

我的代码在这里:

@Controller
@RequestMapping(value="/guestbook")
public class GuestBookController {


     @Autowired
     GuestBookServiceIF guestBookServiceIF; 



     @ModelAttribute("messagesModel")
     public List<UserMessage> getMessagesModel() {
          return guestBookServiceIF.fetchAllService();
        }


     @RequestMapping(method = RequestMethod.GET)
     public String renderGuestBook(Model model) {
         GuestBookBackObject guestBookBackObject = new GuestBookBackObject();
         model.addAttribute("guestBookBackObject", guestBookBackObject);
         return "book";
        }



        @RequestMapping(method=RequestMethod.POST)
        public String saveGuestBookMessage(@ModelAttribute(value="guestBookBackObject") GuestBookBackObject guestBookBackObject, 
                                                                                                    BindingResult buindingResult) {


            guestBookBackObject.setIsNameExist(guestBookServiceIF.isUserInDBService(guestBookBackObject.getUser().getUserName()));

            GuestBookValidation validator = new GuestBookValidation();
            validator.validate(guestBookBackObject, buindingResult);
            if(buindingResult.hasErrors()) {    
                return "book";      
            } else {

            guestBookBackObject.getUserMessage().setTheUser(guestBookBackObject.getUser());
            guestBookServiceIF.saveMessageService(guestBookBackObject.getUserMessage());

            return "redirect:/guestbook";

            }
     }
saveGuestBookMessage()

应该在执行其余代码之前进行一些验证。我的验证的一点是它检查数据库中是否有相同的用户名,如果数据库中存在用户名,那么在jsp页面上应该呈现一些错误消息,例如:“选择不同的名称”,例如为此目的是isUserInDBService()方法

这是我的验证码:

@Component
public class GuestBookValidation implements Validator{


    @SuppressWarnings("rawtypes")
    @Override
    public boolean supports(Class clazz) {
        return GuestBookBackObject.class.isAssignableFrom(clazz);
    }


    @Override
    public void validate(Object obj, Errors error) {


        GuestBookBackObject guestBookBackObject = (GuestBookBackObject)obj;

        if(guestBookBackObject.equals(obj)) {

            ValidationUtils.rejectIfEmpty(error, "user.userName", "", "\u041D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u043E \u0432\u0432\u0435\u0441\u0442\u0438 \u0438\u043C\u044F");
            ValidationUtils.rejectIfEmptyOrWhitespace(error, "userMessage.theMessage", "", "\u042D\u0442\u043E \u043F\u043E\u043B\u0435 \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043F\u0443\u0441\u0442\u044B\u043C");


            if(guestBookBackObject.getIsNameExist()== null) {

                ValidationUtils.rejectIfEmpty(error, "user.userName", "", "Please choose different user name");

            }

        } else {

            try {
                throw new Exception("Object of referance variable obj not equal referance variable guestBookBackObject");
            } catch (Exception e) {
                e.printStackTrace();
            }

        }       

    }

基本上它应该可以正常工作,但它会出错:

Hibernate: insert into USER_DESC (USER_NAME) values (?)
WARN : org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 1062, SQLState: 23000
ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Duplicate entry 'we' for key 'UK_ok6uvp3eyniad0xua3xdt5icw'
Oct 01, 2013 9:27:04 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/web] threw exception [Request processing failed; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'we' for key 'UK_ok6uvp3eyniad0xua3xdt5icw'
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.Util.getInstance(Util.java:386)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4190)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4122)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2818)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2157)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2460)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2377)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2361)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133)
    at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96)
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2975)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3487)
    at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377)
    at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:214)
    at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:194)
    at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:178)
    at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:321)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:286)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:206)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:191)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:114)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
    at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:735)
    at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:727)
    at org.hibernate.engine.spi.CascadingAction$5.cascade(CascadingAction.java:258)
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:388)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:331)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:209)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:166)
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:424)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:263)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:206)
    at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:191)
    at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
    at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:764)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:756)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:752)
    at demidov.pkg.persistence.GuestBookDAOImpl.saveMessage(GuestBookDAOImpl.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at com.sun.proxy.$Proxy8.saveMessage(Unknown Source)
    at demidov.pkg.service.GuestBookServiceImpl.saveMessageService(GuestBookServiceImpl.java:27)
    at demidov.pkg.web.GuestBookController.saveGuestBookMessage(GuestBookController.java:60)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)

它告诉数据库中存在值,该值应该是唯一的。好!但是为什么Validator首先允许插入值而不检查它们

我的后台对象(GuestBookBackObject):

@Component
public class GuestBookBackObject {

    private UserMessage userMessage;

    public UserMessage getUserMessage() {
        return userMessage;
    }
    public void setUserMessage(UserMessage userMessage) {
        this.userMessage = userMessage;
    }


    private User user;

    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }


    private User isNameExist;

    public User getIsNameExist() {
        return isNameExist;
    }
    public void setIsNameExist(User isNameExist) {
        this.isNameExist = isNameExist;
    }

}
谢谢。

2 个答案:

答案 0 :(得分:0)

缺乏更多信息,例如GuestBookBackObject的实施。但根据你给出的内容

因为你永远不会在数据库中检查你要插入的值是否存在于一个被认为是唯一的列中,所以抛出了你所得到的异常。

您应该在验证器内或保存之前的任何位置实现此功能。例如

boolean exists = guestBookServiceIF.isMessageExists(guestBookBackObject);

数据库找出你违反约束的唯一方法是执行该语句。

答案 1 :(得分:0)

要存储验证消息,您调用的方法是错误的。

if(guestBookBackObject.getIsNameExist()== null) {
    ValidationUtils.rejectIfEmpty(error, "user.userName", "", "Please choose different user name");
}

如果设置了属性,但用户名不为空,则不会设置任何内容。您只需在reject对象上调用Errors方法。

if(guestBookBackObject.getIsNameExist()== null) {
    errrors.reject("username.not.unique", "Please choose different user name");
}

接下来,您应该在Validator内进行检查,而不是您的控制器。这样你就可以让Spring为你做所有繁重的工作。