Jpa JDodeTachedFeldAccessException:您刚刚尝试访问字段";附件「;但是,当您分离对象时,此字段未分离

Jpa JDodeTachedFeldAccessException:您刚刚尝试访问字段";附件「;但是,当您分离对象时,此字段未分离,jpa,datanucleus,detach,lob,Jpa,Datanucleus,Detach,Lob,实体类: public class CustomerSurvey implements Serializable { @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="CUSTOMER_SURVEY_SEQUENCE") @Column(name = "SURVEYID", nullable = false) private String surveyId; @Column(name="ATTACHM

实体类:

public class CustomerSurvey implements Serializable {

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



@Column(name="ATTACHMENT")
@Lob
private byte[] attachment;
....
持久性类/逻辑:

 public List<CustomerSurvey> getSurveysByCustomer(String custNo)
        throws WorkServiceException {
    EntityManager em = entityManagerFactory.createEntityManager();
    Query query = em.createNamedQuery("customerSurvey.findByCustomer")
            .setParameter("custNo", custNo);
    logger.debug(query);
    List<CustomerSurvey> surveys = query.getResultList();
    em.clear();
    em.close();
    return surveys;
}
   List<CustomerSurvey> reviewSurveys = workService.getSurveysByCustomer("testCNo2");
    for(CustomerSurvey rsurvey: reviewSurveys) {
        Object obj = rsurvey.getAttachment();
        byte[] buffer = (byte[]) obj;
OutputStream out = new FileOutputStream("C:\\Temp\\TulipsOut.jpg");
        out.write(buffer);
    }
公共列表getSurveysByCustomer(字符串custNo)
抛出WorkServiceException{
EntityManager em=EntityManager工厂。createEntityManager();
Query Query=em.createNamedQuery(“customerSurvey.findByCustomer”)
.setParameter(“custNo”,custNo);
调试(查询);
列表调查=query.getResultList();
em.clear();
em.close();
回归调查;
}
消费者类别/逻辑:

 public List<CustomerSurvey> getSurveysByCustomer(String custNo)
        throws WorkServiceException {
    EntityManager em = entityManagerFactory.createEntityManager();
    Query query = em.createNamedQuery("customerSurvey.findByCustomer")
            .setParameter("custNo", custNo);
    logger.debug(query);
    List<CustomerSurvey> surveys = query.getResultList();
    em.clear();
    em.close();
    return surveys;
}
   List<CustomerSurvey> reviewSurveys = workService.getSurveysByCustomer("testCNo2");
    for(CustomerSurvey rsurvey: reviewSurveys) {
        Object obj = rsurvey.getAttachment();
        byte[] buffer = (byte[]) obj;
OutputStream out = new FileOutputStream("C:\\Temp\\TulipsOut.jpg");
        out.write(buffer);
    }
List reviewSurveys=workService.getSurveysByCustomer(“testCNo2”);
用于(客户调查:reviewSurveys){
Object obj=rsurvey.getAttachment();
字节[]缓冲区=(字节[])obj;
OutputStream out=新文件OutputStream(“C:\\Temp\\TulipsOut.jpg”);
输出。写入(缓冲区);
}
我得到的错误是:

原因:javax.jdo.jdocatedFeldAccessException:您刚刚尝试访问字段“附件”,但在分离对象时未分离此字段。不要访问此字段,或者在分离obj时将其分离 发射型计算机断层扫描仪。 位于com.ge.dsp.iwork.entity.CustomerSurvey.jDogeStatement(CustomerSurvey.java) 在com.ge.dsp.iwork.entity.CustomerSurvey.getAttachment(CustomerSurvey.java:89)上 在com.ge.dsp.iwork.test.WorkServiceTest.testSubmitSurveyResponse(WorkServiceTest.java:270)上 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 位于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.InvokeCustominetMethod(AbstractAutowireCapableBeanFactory.java:1581) 位于org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1522) 位于org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452) ... 14多


谢谢,

主要问题是
私有字节[]附件

  • @Log
    属性的默认加载将是
    FetchType.LAZY
  • 在执行
    EntityManager
    clear()
    过程后,
    持久化上下文将被清除。这意味着所有托管实体都将成为分离状态。更多信息请参阅
  • 实体
    处于分离状态时,如果您访问获取值,您将遇到您提到的问题 简短回答:

    em.clear()
    过程之后,您的实体实例
    将被分离。这就是为什么您无法检索值
    附件
    ,因为
    附件
    是延迟加载(
    FetchType.lazy

    解决方案:使用
    FetchType.EAGER
    。我认为,大多数人不建议使用急切加载

        @Column(name="ATTACHMENT")
        @Basic(fetch = FetchType.EAGER)
        @Lov
        private byte[] attachment;
    

    谢谢你,这很有效。我是JPA的新手。当我们说不建议立即加载时,那么这种情况下的替代方法是什么?需要时,我如何获取/加载这些信息?@beetri,我很抱歉“我认为,大多数人不建议使用即时加载。”这可能是我缺乏经验。主要是,如果您想获得
    CustomerSurvey
    以及
    附件
    ,请使用
    EAGER
    。否则,请使用
    LAZY
    。参考: