【问题标题】:EntityManager refresh problemEntityManager 刷新问题
【发布时间】:2011-01-05 10:03:00
【问题描述】:

当我调用刷新函数时,我的 EntityManager 收到此错误。

public void saveProduct(Product product) {
    entityManager.refresh(product);
}

我听说这可能是 Spring/Hibernate 的一个错误,但我不知道如何解决这个问题。

编辑: 错误是

java.lang.IllegalArgumentException: Entity not managed
org.hibernate.ejb.AbstractEntityManagerImpl.refresh(AbstractEntityManagerImpl.java:268)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:358)
$Proxy17.refresh(Unknown Source)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:198)
$Proxy11.refresh(Unknown Source)
springapp.repository.JdbcProductDao.saveProduct(JdbcProductDao.java:66)
springapp.service.SimpleProductManager.increasePrice(SimpleProductManager.java:28)
springapp.web.PriceIncreaseFormController.onSubmit(PriceIncreaseFormController.java:39)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:421)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:136)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:326)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:313)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

【问题讨论】:

    标签: hibernate spring orm jpa entitymanager


    【解决方案1】:

    来自EntityManager的文档:

    IllegalArgumentException - 如果不是实体或实体不受管理

    1. 检查您的实体是否已映射(使用@Entity,或使用.xml 配置)
    2. 您的实体必须是持久的 - 即由 entityManager 管理。因此,如果您的实体已分离,请先merge() 它,然后再refresh() 它。

    【讨论】:

    • 我编辑了我的代码来做到这一点:getEntityManager().refresh(getEntityManager().merge(product));我检查了我是否映射了@Entity。但还是同样的问题
    • 您的 getEntityManager() 是否每次都打开一个新的 EM?如果是这样,您在一个休眠会话中是 merging 一个实体,而在另一个休眠会话中是 refreshing 它。
    • @Luka Klepec 我如何检查我的 EntityManager 是否每次都打开一个新的 EM?我正在使用持久性管理器
    【解决方案2】:
    public void saveProduct(Product product) {
        ...
    
        Product managedProductEntity = entityManager.find(Product.class, product.getId());
        entityManager.refresh(managedProductEntity);
    
        ...
    }
    

    以这种方式工作。 managedProductEntity 将被托管,因此可以从数据库中刷新。

    【讨论】:

      【解决方案3】:

      如果product 对象刚刚创建,则不能refresh() 它,因为数据库中没有包含对象原始值的行。您首先必须 persist() product 然后 flush() 实体管理器,然后 refresh() 是可能的。

      【讨论】:

        【解决方案4】:

        如果一个对象被分离,它也不能被刷新。想知道它是否可能是一个错误......只需看看 AbstractEntityManagerImpl 的第 730-733 行(Hibernate 3.6.0.Final ?):

            public void refresh(Object entity, LockModeType lockModeType, Map<String, Object> properties) {
            ...
                if ( !getSession().contains( entity ) ) {
                    throw new IllegalArgumentException( "Entity not managed" );
                }
            ...
        

        【讨论】:

          【解决方案5】:

          传递一个空实体将返回同样的错误。当我们第一次实现刷新例程时,我们的应用程序中遇到了这个问题,并且由于实体都是托管的,所以无法理解它。托管实体的空实例显然不算数!

          【讨论】:

            猜你喜欢
            • 2011-04-29
            • 2011-08-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-02-11
            • 2012-04-19
            • 2011-08-04
            相关资源
            最近更新 更多