gpt4 book ai didi

java - Hibernate JPA 删除分离的对象

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:27:40 26 4
gpt4 key购买 nike

我在我们的服务层中有这段代码:

@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));
}
}

但是,如果我用它来删除实体,它将失败并显示:

Caused by: java.lang.IllegalArgumentException: Removing a detached instance FooEntity
at org.hibernate.ejb.event.EJB3DeleteEventListener.performDetachedEntityDeletionCheck(EJB3DeleteEventListener.java:65)
at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:107)
at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:73)
at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:956)
at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:934)
at org.hibernate.ejb.AbstractEntityManagerImpl.remove(AbstractEntityManagerImpl.java:867)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
at $Proxy42.remove(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
at $Proxy31.remove(Unknown Source)
... 16 more

但这对我来说毫无意义,因为 em.remove(ee) 之前的行,实体是通过 find 方法加载的,因此它不能被分离...事务是通过 spring 实现的xml配置

//编辑:添加反序列化方法。基本上,它将获取与每个对象一起存储的 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 和 google,我设法找到了解决它的方法:

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

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

关于java - Hibernate JPA 删除分离的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19706883/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com