如何在 JPA 中分离关联对象

Posted

技术标签:

【中文标题】如何在 JPA 中分离关联对象【英文标题】:How to detache an associated object in JPA 【发布时间】:2012-10-09 20:07:03 【问题描述】:

我已经使用 em.clear() 分离了所有实体,但我没有看到关联的对象被分离?如何分离关联对象?

 I have a method as : 

 public CustomerSurvey getSurveyByRequest(long requestNo)
        throws WorkServiceException 
    logger.debug("Inside getSurveyByRequest : " + requestNo);
    EntityManager em = entityManagerFactory.createEntityManager();
    Query query = em.createNamedQuery("customerSurvey.findByRequest")
            .setParameter("srNo", requestNo);
    List<CustomerSurvey> surveys = query.getResultList();
    **em.clear();**
    em.close();
    return surveys.get(0);

客户调查.java:

@Entity
@Table(name = "CUSTOMER_SURVEY", uniqueConstraints =  @UniqueConstraint(columnNames 
= "SERVEYID") )
@SequenceGenerator(name="CUSTOMER_SURVEY_SEQUENCE", 
sequenceName="CUSTOMER_SURVEY_SEQUENCE", initialValue=1, allocationSize=100)

@NamedQueries(
@NamedQuery(name="customerSurvey.findByRequest",
        query="SELECT survey FROM CustomerSurvey survey " +
                "WHERE survey.serviceRequest.srNo = :srNo")
)

public class CustomerSurvey implements Serializable 

@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, 
generator="CUSTOMER_SURVEY_SEQUENCE")
@Column(name = "SURVEYID", nullable = false)
private String surveyId;

     @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.DETACH)
@JoinColumn(name="CUSTNO", referencedColumnName="CustNO")
private Customer customer;

@Column(name="AVGRATINGS")
private int avgRatings;

@Column(name="COMMENTS")
private String comments;

@Column(name="SENTON")
private Date sentOn;

@Column(name="RESPONDEDON")
private Date respondedOn;

@OneToMany(fetch=FetchType.LAZY,mappedBy="customerSurvey")
private Set<SurveyResponse> responses;

@OneToOne(fetch=FetchType.LAZY)
@JoinColumn(name="SRNO")
private ServiceRequest serviceRequest;

我的测试课:

CustomerSurvey survey = workService.getSurveyByRequest(request.getSrNo());
        System.out.println("survey = " + survey);
        System.out.println("survey id = " + survey.getSurveyId());
        System.out.println("survey customer = " + survey.getCustomer());

错误信息:

调查 = com.ge.dsp.iwork.entity.CustomerSurvey@36b88ea5 调查 ID = 131 线程“SpringOsgiExtenderThread-134” org.springframework.beans.factory.BeanCreationException 中的异常:创建 URL [bundle://178.124:0/META-INF/spring/module- 中定义的名称为“testCloseRequest”的 bean 时出错 context.xml]: init 方法调用失败;嵌套异常是 javax.jdo.JDODetachedFieldAccessException: 您刚刚尝试访问字段“客户”,但当您分离 目的。要么不要访问此字段,要么在分离对象时将其分离。 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 在 org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) 在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) 在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:609) 在 org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) 在 org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:69) 在 org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:355) 在 org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85) 在 org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:320) 在 org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:132) 在 java.lang.Thread.run(Thread.java:662) 原因:javax.jdo.JDODetachedFieldAccessException:您刚刚尝试访问字段“customer”,但在分离对象时未分离此字段。要么不要访问此字段,要么在 分离物体。 在 com.ge.dsp.iwork.entity.CustomerSurvey.jdoGetcustomer(CustomerSurvey.java) 在 com.ge.dsp.iwork.entity.CustomerSurvey.getCustomer(CustomerSurvey.java:89) 在 com.ge.dsp.iwork.test.WorkServiceTest.testCloseRequest(WorkServiceTest.java:181) 在 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.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1581) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1522) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452) ... 14 更多

【问题讨论】:

【参考方案1】:

所有当前加载的字段都已分离。您的字段未急切加载,并且您似乎没有访问过它,因此未加载它,因此未分离。您显然可以访问它,或将其设为 EAGER,或使用 DataNucleus 提取组扩展来加载它。也可以只看日志看分离过程

【讨论】:

在世界上哪里可以找到有关此的文档?

以上是关于如何在 JPA 中分离关联对象的主要内容,如果未能解决你的问题,请参考以下文章

JPA EntityManager 获取关联对象

在spring data jpa中通过@Query更新Entity内部的关联对象

JPA 不生成外键

JPA学习(JPA_映射关联关系)

如何从 R 中的特定包中分离所有对象和方法? [复制]

SpringData JPA多表关联操作