我在Spring Data JPA / Eclipselink环境中有一个这样的实体(主序列不是由序列生成的):
@Entity
@Table(name="MY_ENTITY")
public class MyEntity implements Serializable {
@Id
@Column(insertable=true, updatable=true, nullable=false)
private String propertyid;
\\other columns
}
我试图从表中删除一行并重新插入(使用相同的主键)。
我的方法是调用deleteAll()来清理表,然后保存()新的实体:
@Transactional
public void deleteAndSave(MyEntity entity) {
propertyInfoRepository.deleteAll();
propertyInfoRepository.flush(); // <- having it or not, nothing changes
propertyInfoRepository.save(entity);
}
但这给了我这个错误:
Caused by: java.lang.IllegalArgumentException: Cannot merge an entity that has been removed: com.xxx.MyEntity@1f28c51
at org.eclipse.persistence.internal.sessions.MergeManager.registerObjectForMergeCloneIntoWorkingCopy(MergeManager.java:912)
at org.eclipse.persistence.internal.sessions.MergeManager.mergeChangesOfCloneIntoWorkingCopy(MergeManager.java:494)
at org.eclipse.persistence.internal.sessions.MergeManager.mergeChanges(MergeManager.java:271)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.mergeCloneWithReferences(UnitOfWorkImpl.java:3495)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.mergeCloneWithReferences(RepeatableWriteUnitOfWork.java:378)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.mergeCloneWithReferences(UnitOfWorkImpl.java:3455)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.mergeInternal(EntityManagerImpl.java:486)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.merge(EntityManagerImpl.java:463)
....
我做错了什么? 我不明白为什么它试图合并实体而不是简单地在删除后重新插入它。
感谢您的帮助!
答案 0 :(得分:1)
直接回答你的问题:
问题是您尝试保存的实体已经具有持久标识,即ID,这就是您的存储库将尝试合并而不是保留实体的原因。
如果您看到this question它似乎在Spring Repository的级别上被触发(至少),那么您可以考虑覆盖存储库的save
方法并测试问题是否是还在那里。
答案 1 :(得分:-1)
JPA EntityManager跟踪每个被管实体的状态。在您的情况下,您删除该实体,然后尝试合并它,这会引发异常。我不知道你的方法是否正确(删除然后合并似乎很奇怪),因为你没有提供整个图片,但你可以尝试以下方法:
假设em
是您的EntityManager,entity
是您的实体:
em.remove(entity); //This will perform the delete
MyEntity detachedEntity = em.detach(entity); //Gets a detached copy of the entity, EM will not operated on this unless told to do so (see below)
detachedEntity.setId(null) // Avoid duplicate key violations; Optional since you are deleting the original entity
em.persist(detachedEntity); // This will perform the required insert