spring EntityManager 刷新问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2070073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 03:58:09  来源:igfitidea点击:

EntityManager refresh problem

hibernatespringormjpaentitymanager

提问by Albinoswordfish

I'm getting this error from my EntityManager when I call the refresh function.

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

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

I heard this could be a bug with Spring/Hibernate, however I'm not sure how to get around this.

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

Edit: the error is

编辑:错误是

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)

回答by Bozho

From the docs of EntityManager:

来自以下文档EntityManager

IllegalArgumentException - if not an entity or entity is not managed

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

  1. Check if your entity is mapped (using @Entity, or with .xmlconfiguration)
  2. Your entity must be persistent- i.e. managed by the entityManager. So if your entity is detached, merge()it first, and then refresh()it.
  1. 检查您的实体是否已映射(使用@Entity,或使用.xml配置)
  2. 您的实体必须是持久的——即由 entityManager 管理。因此,如果您的实体是分离的,merge()则首先是它,然后是refresh()它。

回答by Daniel Szalay

public void saveProduct(Product product) {
    ...

    Product managedProductEntity = entityManager.find(Product.class, product.getId());
    entityManager.refresh(managedProductEntity);

    ...
}

Works this way. managedProductEntitywill be managed, and therefore it can be refreshed from database.

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

回答by Danny Groenewegen

If the productobject has just been created, you can't refresh()it, because there is no row in the database with the original values of the object. You first have to persist()the productand then flush()the entitymanager, after that a refresh()is possible.

如果product对象刚刚创建,则不能refresh(),因为数据库中没有包含对象原始值的行。你首先要persist()product,然后flush()EntityManager的,后一个refresh()是可能的。

回答by Nick G.

If an object is detached, it can't be refreshed either. Wonder if it might be a bug... Just take a look at lines 730-733 of AbstractEntityManagerImpl (Hibernate 3.6.0.Final ?):

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

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

回答by user2125247

Passing a null entity will return this same error. We had this problem in our app when we first implemented refresh routines and couldn't make sense of it since the entities were all managed. A null instance of a managed entity obviously doesn't count!

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