EclipseLink 2.7无查询更新实体报错,寻求解决方案
在EclipseLink 2.7中实现无查询更新实体的正确方案
你之前碰到的ClassCastException,大概率是因为直接强转EntityManager到EntityManagerImpl时,这个EntityManager其实是被容器(比如Spring、Java EE容器)代理过的实例,并不是EclipseLink原生的EntityManagerImpl对象,所以强转失败。下面给你两种更可靠的解决方案:
方案一:安全获取EntityManagerImpl并更新
使用JPA标准的unwrap()方法来获取底层的EclipseLink实现类,这个方法会自动处理代理情况,避免类型转换异常:
EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); // 用unwrap安全获取EclipseLink的EntityManagerImpl EntityManagerImpl emImpl = entityManager.unwrap(EntityManagerImpl.class); UnitOfWork unitOfWork = emImpl.getUnitOfWork(); AbstractSession session = unitOfWork.getParent(); session.updateObject(entity); entityManager.getTransaction().commit(); entityManager.close();
方案二:更面向接口的实现(推荐)
其实不用拿到父Session,直接通过JpaEntityManager接口获取UnitOfWork即可,这样依赖的是EclipseLink的公开接口,比依赖具体实现类更稳妥:
EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); // 获取EclipseLink的JpaEntityManager接口实例 JpaEntityManager jpaEntityManager = entityManager.unwrap(JpaEntityManager.class); UnitOfWork unitOfWork = jpaEntityManager.getUnitOfWork(); unitOfWork.updateObject(entity); // UnitOfWork本身就支持更新操作 entityManager.getTransaction().commit(); entityManager.close();
注意事项
- 确保你的实体类有正确的
@Id注解标识主键,否则EclipseLink无法定位要更新的记录。 - 如果实体使用了乐观锁(比如
@Version注解),要保证版本字段的值正确,否则更新可能会失败并抛出乐观锁异常。 - 这种方式是直接使用EclipseLink的内部API,会和EclipseLink绑定,失去JPA的跨ORM框架可移植性,如果以后更换ORM框架需要修改这部分代码。
内容的提问来源于stack exchange,提问作者user5182503
相关产品推荐
相关产品推荐

