【问题标题】:Can not save the foreign key in Spring form select tag无法在 Spring 表单选择标签中保存外键
【发布时间】:2012-12-11 22:35:25
【问题描述】:

我正在尝试保存一个在选择标记中具有外键但始终为空的表单。当我使用检查元素时,它会发布选定的 id,所以我不能说这是表单的问题。有人可以帮忙吗。 表格

   <form:select path="categoryId">
            <form:option value="0" label="   -- Please Select --" />
            <form:options items="${categoryList}"  itemValue="categoryId" itemLabel="categoryName"/>
    </form:select>

控制器

@RequestMapping(value = "product", method = RequestMethod.POST)
public String addNewProduct(@ModelAttribute("product") Product product, Model model){
    model.addAttribute("product", product);
    purchaseOrderService.addProduct(product);
    return "categories";
}

JPA

@Transactional(propagation = Propagation.REQUIRED)
    public boolean saveProduct(Product product) {
        EntityManager em = getEm();
        em.persist(product);
        return true;
    }

持久化对象

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "CATEGORY_ID", referencedColumnName = "CATEGORY_ID")
private Category categoryId;

错误

java.lang.NoClassDefFoundError: org/hibernate/exception/LockTimeoutException
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1328)
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:80)
org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:512)
org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:394)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
$Proxy34.addProduct(Unknown Source)
com.logicalideas.purchaseorder.ProductController.addNewProduct(ProductController.java:30)
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:601)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
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:923)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
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:641)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

根本原因

java.lang.ClassNotFoundException: org.hibernate.exception.LockTimeoutException org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1711) org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556) org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1328) org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300) org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:80) org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:512) org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754) org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723) org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:394) org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120) org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) $Proxy34.addProduct(未知来源) com.logicalideas.purchaseorder.ProductController.addNewProduct(ProductController.java:30) sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:601) org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213) 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:923) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852) 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:641) javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

非常感谢

【问题讨论】:

  • @Zed429:正如您在堆栈跟踪中看到的,这是一个 ClassNotFound 异常。你确定你已经包含了所有需要的库吗?
  • 好吧,当我保存类别时没有问题,那么我还能缺少哪些其他库? Category 和 Product 之间的唯一区别是 Product 有一个外键,由于某种奇怪的原因,它总是为空。
  • 有人请吗???现在有点绝望
  • 感谢 Hoang Long 的输入,我必须更新这些依赖项才能使其正常工作。 org.hibernatehibernate-core4.1.7.Finalorg.hibernate groupId> hibernate-entitymanager4.1.7.Final
  • 很高兴听到您解决了这个问题。抱歉,最近比较忙,没能跟上。对于此类问题(ClassNotFound),保持添加的库之间的版本兼容性很重要。我猜是你的问题。

标签: spring-mvc


【解决方案1】:

当您解决第一个问题(ClassNotFound)时,我认为现在可以了。

第二个问题:

好吧,这已经消除了错误,但它有一个奇怪的行为 现在,即使您在产品控制器中,它也会创建一个新类别 尝试保存具有选定类别(FK)的新产品。然后它添加 这个新创建的 categoryId 与您的相同 选择(名称,而不是 id)到 product.categoryId 中。我真的希望 我没有混淆任何人。我真的很感激。

这不是同一个问题。我认为您误解了 Hibernate 的工作方式。当你让 Spring 机制在这种情况下映射对象时,它总是会创建一个新的 categoryId 对象。另一方面,通过另一种方式,您也许可以让 Spring 理解它们是相同的,但是在尝试编辑类别时会遇到麻烦。

这里的问题是你依赖 Spring 来映射正确的 Hibernate 对象——Spring 映射并不总是好的。相反,我认为您可以将“idOfCategory”之类的参数发送到服务器,通过该 ID 获取 CategoryId 对象,然后将类别设置为您新创建的产品。更好的方法是您只从客户端传输一个 DTO 对象 (ProductDTO),然后在服务器端创建一个成熟的 Hibernate Product 对象。

例如:

@RequestMapping(value = "product", method = RequestMethod.POST)
public String addNewProduct(@ModelAttribute("productDTO") ProductDTO productDTO, Model model){
    model.addAttribute("product", product);
    Product product = new Product(productDTO);
    CategoryId id = productService.getCategoryById(productDTO.getCategoryId());
    product.setCategoryId(id);
    purchaseOrderService.addProduct(product);
    return "categories";
}

【讨论】:

  • 感谢 Hoang Long 提供了很大的帮助。但是,我使用@initBinder 以不同的方式完成了它,这稍微长了一点,但确实很神奇。我从这里得到了一些帮助:- raymondhlee.wordpress.com/2011/06/08/…
  • @Zed420:很高兴听到您解决了问题 :) 并感谢您的评论,现在我知道了另一种选择 :)
猜你喜欢
  • 2016-05-23
  • 2011-02-24
  • 1970-01-01
  • 2010-09-14
  • 2020-04-20
  • 2013-10-02
  • 2020-01-16
  • 1970-01-01
  • 2013-10-11
相关资源
最近更新 更多