目前,我有我的控制器下面的映射:只有一個上發佈添加/編輯方法
@RequestMapping(value = "/add.html", method = RequestMethod.GET)
public String showAddForm(Map<String, Object> map)
{
map.put("person", new Person());
return "form";
}
@RequestMapping(value = "/add.html", method = RequestMethod.POST)
public String processAddForm(@ModelAttribute("person") @Valid Person person, BindingResult result, Map<String, Object> map)
{
if (service.findByName(person.getName()) != null)
{
result.addError(new FieldError("person", "name", "Person already exists"));
}
if (result.hasErrors())
{
return "form";
}
service.save(person);
return "redirect:/index.html";
}
@RequestMapping(value = "/{id}/edit.html", method = RequestMethod.GET)
public String showEditForm(@PathVariable("id") int id, Map<String, Object> map)
{
map.put("person", service.load(id));
return "form";
}
@RequestMapping(value = "/{id}/edit.html", method = RequestMethod.POST)
public String processEditForm(@PathVariable("id") int id, @ModelAttribute("person") @Valid Person person, BindingResult result)
{
Person p;
if ((p = service.findByName(person.getName())) != null && person.getId() != id)
{
result.addError(new FieldError("person", "name", "Person already exists"));
}
if (result.hasErrors())
{
return "form";
}
person.setId(id);
service.save(person);
return "redirect:/index.html";
}
這怎麼可能,以減少冗餘代碼? 也許通過設置形式的行動,以/save.html並結合processAddForm和processEditForm到
@RequestMapping(value = "/save.html", method = RequestMethod.POST)
但代碼應該看起來怎麼樣呢? 我只是嘗試,並得到一些例外,因爲已經有人物#在會話實例...
編輯 在這裏,我給它一個嘗試...
控制器的方法:
@RequestMapping(value = "/save.html", method = RequestMethod.POST)
public String onSubmit(@ModelAttribute("person") @Valid Person person, BindingResult result, Map<String, Object> map)
{
Person p;
if ((p = service.findByName(person.getName())) != null)
{
if (person.getId() != p.getId())
{
result.addError(new FieldError("person", "name", "Person already exists"));
}
}
if (result.hasErrors())
{
return "form";
}
service.save(person);
return "redirect:/index.html";
}
形式:
<c:url value="/save.html" var="formAction" />
<form:form modelAttribute="person" action="${formAction}" method="post">
<form:errors path="*" cssClass="error" element="div" />
<form:hidden path="id" />
<form:label path="name">Name:</form:label>
<form:input path="name" />
<input type="submit" value="Submit" />
</form:form>
添加的作品,但編輯給出以下Excep重刑:
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.example.entities.Person#7]
org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:637)
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:305)
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:112)
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:677)
org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:669)
org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:665)
com.example.dao.PersonDaoImpl.save(PersonDaoImpl.java:30)
com.example.dao.PersonDaoImpl.save(PersonDaoImpl.java:1)
com.example.services.PersonServiceImpl.save(PersonServiceImpl.java:29)
com.example.services.PersonServiceImpl.save(PersonServiceImpl.java:1)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:616)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
$Proxy44.save(Unknown Source)
com.example.controller.PersonController.onSubmit(PersonController.java:65)
com.example.controller.PersonController$$FastClassByCGLIB$$9c2dc698.invoke(<generated>)
net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:61)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
com.example.controller.PersonController$$EnhancerByCGLIB$$a0aff0d2.onSubmit(<generated>)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:616)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:212)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:101)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:201)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
EDIT2: PersonServiceImpl:
@Override
@Transactional
public void save(Person person)
{
dao.save(person);
}
PersonDaoImpl:
@Override
public void save(Person person)
{
try
{
sessionFactory.getCurrentSession().saveOrUpdate(person);
}
catch(NonUniqueObjectException e)
{
sessionFactory.getCurrentSession().merge(person);
}
}
這是正確的方法是什麼?也許更好的解決方案?
EDIT3
@Override
public void save(Person person)
{
if (load(person.getId()) != null)
{
sessionFactory.getCurrentSession().merge(person);
}
else
{
sessionFactory.getCurrentSession().save(person);
}
}
@Override
public Person load(int id)
{
return (Person) sessionFactory.getCurrentSession().load(Person.class, id);
}
這是一個更好的解決辦法?
因此,這實際上是一個Hibernate異常,並且與Spring MVC無關。閱讀堆棧跟蹤的其餘部分(我無法讀取它,你沒有按照問題發佈),併發布代碼,如果你不明白它的話。 – 2012-02-08 15:48:23