JDODetachedFieldAccessException: вы только что попытались получить доступ к полевому "прикреплению", но это поле не было отключено, когда вы отсоединили объект

Класс сущностей:

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;
}
</customersurvey></customersurvey>

потребительский класс/логика:

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);
 }
</customersurvey>

Ошибка:

Вызвано: javax.jdo.JDODetachedFieldAccessException: вы только что попытались получить доступ к полевому "прикреплению", но это поле не было отсоединено, когда вы отсоединили объект. Либо не обращайтесь к этому полю, либо отсоединяйте его при отсоединении объекта obj ЭСТ.       на com.ge.dsp.iwork.entity.CustomerSurvey.jdoGetattachment(CustomerSurvey.java)       на com.ge.dsp.iwork.entity.CustomerSurvey.getAttachment(CustomerSurvey.java:89)       at com.ge.dsp.iwork.test.WorkServiceTest.testSubmitSurveyResponse(WorkServiceTest.java:270)       at sun.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод)       at 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 ответ

Основная проблема - private byte[] attachment;.

  • По умолчанию атрибут @Log по умолчанию будет FetchType.LAZY.
  • Persistence Context будет понятным после процесса clear() EntityManager. Это означает, что все управляемые объекты станут отсоединенными. Дополнительная информация здесь.
  • Когда состояние Entity находится в состоянии отсоединения, если вы получаете доступ к выборке, вы получите эту проблему по мере упоминания.

Короткий ответ:

После процесса em.clear() ваш экземпляр объекта surveys будет отсоединен. Поэтому вы не можете получить значение attachment из-за attachment - это ленивая загрузка (FetchType.LAZY).

Решение: используйте FetchType.EAGER. Я думаю, что большинство людей не рекомендуют использовать активную загрузку.

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

licensed under cc by-sa 3.0 with attribution.