Java Hibernate JPA删除分离的对象

Java Hibernate JPA删除分离的对象,java,spring,hibernate,jpa,web,Java,Spring,Hibernate,Jpa,Web,我在我们的服务层中有以下代码: @Override public <T extends BaseEntity> T find(Long id, Class<? extends BaseEntity> clazz) throws Exception { BaseEntity e = em.find(clazz, id); if (e != null) { deserialize(e, e.getClass()); } else

我在我们的服务层中有以下代码:

@Override
public <T extends BaseEntity> T find(Long id, Class<? extends BaseEntity> clazz) throws Exception {
    BaseEntity e = em.find(clazz, id);
    if (e != null) {
        deserialize(e, e.getClass());
    } else
        LOG.error("Found null for id " + id);
    return (T) e;
}

public void delete(BaseEntity e, String index, String type) throws Exception {
    if (e == null)
        return;
    if (e.getId() == null)
        return;
    Delete delete = new Delete.Builder(e.getId().toString()).index(index).type(type).build();
    getJestClient().execute(delete);
    if (em.contains(e)) {
        em.remove(e);
    } else {
        BaseEntity ee = find(e.getId(), e.getClass());
        em.remove(ee);
    }
}

 protected void deserialize(BaseEntity dst, Class<?> dstClass) throws Exception {
    Object src  = serializer.deserialize(new String(dst.getContent(), "UTF-8"), dstClass);

    for (Field f : getClassFields(src.getClass())) {
        if (Modifier.isStatic(f.getModifiers())) continue;
        if (!f.isAnnotationPresent(Expose.class)) continue;

        f.setAccessible(true);

        f.set(dst, f.get(src));
        LOG.trace("deserializing " + f.getName() + " : " + f.get(src));
    }
}
但这对我来说毫无意义,因为
em.remove(ee)
之前的行是通过find方法加载实体的,所以它不能被分离。。。事务是通过SpringXML配置实现的

//编辑:添加了反序列化方法。基本上,它将获取存储在每个对象中的json内容,并创建对象的副本,然后将字段分配给该副本。 getJestClient().execute是elasticsearch的处理程序,它与hibernate和jpa无关

Em是通过spring创建的:

 <bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dsFoo">
    <property name="driverClassName" value="${foo.census.driverClassName}"/>
    <property name="url" value="${foo.census.url}"/>
    <property name="username" value="${foo.census.user}"/>
    <property name="password"   value="${foo.census.password}"/>
    <property name="testOnBorrow" value="true"/>
    <property name="testOnReturn" value="true"/>
    <property name="testWhileIdle" value="true"/>
    <property name="timeBetweenEvictionRunsMillis" value="1800000"/>
    <property name="numTestsPerEvictionRun" value="3"/>
    <property name="minEvictableIdleTimeMillis" value="1800000"/>
    <property name="validationQuery" value="SELECT 1"/>
</bean>

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="emfCensus">
    <property name="persistenceUnitName" value="puFoo"/>
    <property name="dataSource"          ref="dsFoo"/>
</bean>

<bean id="emFoo" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
    <property name = "entityManagerFactory" ref="emfFoo"/>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="emfFoo" />
    <property name="persistenceUnitName"  value="puFoo" />
</bean>

<bean id="repoFoo" class="service.FooService">
    <property name="entityManager" ref="emFoo" />
</bean>

<aop:aspectj-autoproxy proxy-target-class="true"/>

<aop:config>
    <aop:pointcut id="repoFooOperation" expression="execution(* service.FooService.*(..))"/>
    <aop:advisor advice-ref="txAdviceFoo" pointcut-ref="repoFooOperation"/>
</aop:config>

<tx:advice id="txAdviceFoo" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

好的,多亏了stackoverflow和谷歌搜索,我终于找到了解决问题的方法:

    if (em.contains(e)) {
        em.remove(e);
    } else {
        BaseEntity ee = em.getReference(e.getClass(), e.getId());
        em.remove(ee);
    }

是删除已分离实体的正确方法

是什么使行
反序列化(e,e.getClass())?这是干什么的?getJestClient().execute(delete);
反序列化的作用是什么?删除对问题不重要的代码()em的范围是什么?您是如何初始化它的?即使我在delete方法的末尾做了类似的操作:
if(em.contains(e)){em.remove(e);}else{BaseEntity ee=em.find(e.getClass(),e.getId();em.remove(ee);}
它仍然会失败,并出现相同的错误……发现这也很有用:
    if (em.contains(e)) {
        em.remove(e);
    } else {
        BaseEntity ee = em.getReference(e.getClass(), e.getId());
        em.remove(ee);
    }