【问题标题】:PersistentObjectException: detached entity passed to persist while removing entity with composite keyPersistentObjectException:分离的实体传递给持久化,同时使用复合键删除实体
【发布时间】:2015-09-25 13:20:08
【问题描述】:

我在 JPA/Hibernate 中遇到奇怪的错误...我得到了

PersistentObjectException: detached entity passed to persist

尝试删除具有由 ProviderId 和 ServicePointNumber 组成的复合键的 ServicePoint 实体时。 (Provider 是另一个实体,ServicePoint 表示依赖于 Provider 实体的弱实体)。

代码如下:

@DELETE
        @Path("/{servicePointNumber : \\d+}")
        @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
        public Response removeServicePoint( @PathParam("userId") Long userId,
                                            @PathParam("servicePointNumber") Integer servicePointNumber,
                                            @BeanParam GenericBeanParam params) throws ForbiddenException, NotFoundException {

            if(params.getAuthToken() == null) throw new ForbiddenException("Unauthorized access to web service.");
            logger.log(Level.INFO, "removing given Service Point by executing ProviderResource.ServicePointResource.removeServicePoint(userId, servicePointNumber) method of REST API");

            // find ServicePoint entity that should be deleted
            ServicePoint toDeleteServicePoint = servicePointFacade.find( new ServicePointId(userId, servicePointNumber) );
            // throw exception if entity hasn't been found
            if(toDeleteServicePoint == null)
                throw new NotFoundException("Could not find service point to delete for given id: " + userId + ".");

            // remove entity from database
            servicePointFacade.remove(toDeleteServicePoint);

            return Response.status(Status.NO_CONTENT).build();
        }

及实体外观移除方法的实现:

public void remove(@NotNull T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

【问题讨论】:

  • 您使用什么进行事务管理?完整的堆栈跟踪和复合键的代码也很有启发性。
  • 我在删除方法上使用@Stateless session bean Transaction type REQUIRED。另一方面,removeServicePoint 没有任何事务,它是 JAX-RS Resource 类的方法。我曾尝试使用 \@Transactional 但这没有帮助。 \@Transactional 似乎不起作用?这个资源类是另一个资源类的非静态子类。我已经解决了使用 \@NamedQuery: DELETE FROM ServicePoint sp WHERE sp.provider.userId = :userId AND sp.servicePointNumber = :servicePointNumber 的问题。它有效,但我不能只使用实体管理器 .remove() 方法删除似乎很奇怪
  • getEntityManager()方法的实现是什么?
  • 它只是返回 EntityManger 对象。由于此方法 (remove()) 位于 AbstractFacade 中,并在子类上设置了 EntityManager 属性,并且具有应该重写的抽象方法并返回适合给定实体的 EntityManager

标签: hibernate jakarta-ee jpa ejb


【解决方案1】:

您是否曾经使用过 Evict?还是一些 session.clear?

【讨论】:

  • 不,我没有使用复合主键的问题,并且提供者 ID 是从提供者实体继承的......并且此提供者实体已分离。具有单个主键字段的相同代码可以正常工作。
  • 我也试过在这个方法上使用@Transactional注解,但没有帮助
猜你喜欢
  • 1970-01-01
  • 2015-12-26
  • 2016-05-12
  • 2012-11-02
  • 1970-01-01
相关资源
最近更新 更多