EntityManager refresh problem
I'm getting this error from my EntityManager when I call the refresh function.
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.
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:7开发者_如何学Go17)
From the docs of EntityManager
:
IllegalArgumentException - if not an entity or entity is not managed
- Check if your entity is mapped (using
@Entity
, or with.xml
configuration) - Your entity must be persistent - i.e. managed by the entityManager. So if your entity is detached,
merge()
it first, and thenrefresh()
it.
public void saveProduct(Product product) {
...
Product managedProductEntity = entityManager.find(Product.class, product.getId());
entityManager.refresh(managedProductEntity);
...
}
Works this way. managedProductEntity
will be managed, and therefore it can be refreshed from database.
If the product
object 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 product
and then flush()
the entitymanager, after that a refresh()
is possible.
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 ?):
public void refresh(Object entity, LockModeType lockModeType, Map<String, Object> properties) {
...
if ( !getSession().contains( entity ) ) {
throw new IllegalArgumentException( "Entity not managed" );
}
...
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!
精彩评论