在一個保存業(yè)務(wù)數(shù)據(jù)的方法里面暂殖,有時會報錯价匠,有時候又正常,報錯信息如下:
org.hibernate.HibernateException: identifier of an instance of com.entity.Attachment was altered from f65d63296e2a4070a7f2d168a31e9fa1 to 06bf0bea595e4ef4b283e823737af3cb
at org.hibernate.event.internal.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:80)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:192)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:152)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:231)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:102)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:55)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1258)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1335)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
從報錯信息看呛每,是保存附件的時候有問題了(Attachment是附件的實體)踩窖。看一下業(yè)務(wù)邏輯晨横,把一個業(yè)務(wù)單據(jù)復(fù)制一下洋腮,生成一個歷史記錄,所以附件也必須復(fù)制一份手形。
看代碼:
// 從數(shù)據(jù)庫中查出原有數(shù)據(jù)
List<Attachment> attachmentList = attachmentService.getAttachmentList();
// 整理數(shù)據(jù)
if (attachmentList .size() > 0) {
attachmentList .forEach(a -> {
a.setId(null);
a.setBizId(newBizId);
});
// 重新保存一份
iAttachmentService.save(attachmentList );
}
這段代碼會報錯啥供,后來修改一下,改成如下代碼:
// 從前端傳來的數(shù)據(jù)中库糠,取出附件信息
List<Attachment> attachmentList = saveData.getAttachmentList();
List<Attachment> newAttachmentList = new ArrayList();
// 整理數(shù)據(jù)
if (attachmentList .size() > 0) {
attachmentList .forEach(a -> {
Attachment newAttachment = new Attachment();
// 一個工具類伙狐,org.springframework.beans.BeanUtils.copyProperties(source, target)
BeanUtil.copyBeanProperties(a,newAttachment );
newAttachment .setId(null);
newAttachment .setBizId(newBizId);
newAttachmentList.add(newAttachment );
});
iAttachmentService.save(newAttachmentList);
}
結(jié)果,沒有再報上面的錯誤曼玩。
原因分析:原本的方法鳞骤,遍歷ArrayList的時候把ID set為null, save的時候會重新賦值,對于hibernate來說黍判,原來的對象還是在session中的(清一下session可能行)
參考:
https://blog.csdn.net/dly120219891208/article/details/41244449
https://stackoverflow.com/questions/4179166/hibernate-how-to-fix-identifier-of-an-instance-altered-from-x-to-y