java - 无法在 Spring-boot 中找出具有相同标识符值的对象
问题描述
“trace”:“org.springframework.dao.DataIntegrityViolationException:具有相同标识符值的不同对象已与会话关联:[com.ffcalendar.calendarDemo.models.User#1];嵌套异常是 javax.persistence.EntityExistsException :具有相同标识符值的不同对象已与会话关联:[com.ffcalendar.calendarDemo.models.User#1]\r\n\tat org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java :400)\r\n\tat org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:235)\r\n\tat org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java :551)\r\n\tat org.springframework.dao.support。ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)\r\n\tat org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)\r\n\tat org.springframework.dao.support.PersistenceExceptionTranslationInterceptor。调用(PersistenceExceptionTranslationInterceptor.java:152)\r\n\tat
解决方案
“具有相同标识符值的不同对象已与会话关联”
在持久性上下文中只允许 1 个具有特定 id 的托管实例。这意味着对于特定类,您只能拥有 1 个实例,例如id =322
,该实例被认为处于 JPA 的托管状态。如果您有来自同一类的另一个具有相同 Id 的分离实例,并且您尝试重新附加它,那么您会收到您遇到的错误。
如果您提供有关如何保存这些实体的更多信息,我们将能够找到错误所在。
根本原因就是我所描述的。
编辑:在问题中提供更多信息后
我有很多怀疑,因为你的代码看起来不是很干净,但无论如何我都会从显而易见的开始
public class CalendarEvent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((eventDateTime == null) ? 0 : eventDateTime.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CalendarEvent other = (CalendarEvent) obj;
if (eventDateTime == null) {
if (other.eventDateTime != null)
return false;
} else if (!eventDateTime.equals(other.eventDateTime))
return false;
return true;
}
}
在此处查看您的代码的这一部分。对于 JPA,您已声明实体将用Long id
.
但是,稍后您提供了一个 equals 和一个仅考虑eventDateTime
.
所以一个包含 CalendarEvents 的列表可以有多个具有相同 id 和不同 eventDateTime 的 CalendarEvents。这对 JPA 来说绝对是错误的。
首先实现仅考虑 Long id 字段的 equals 和 hashcode。如果这不是特定的根本原因,我们会走得更远,但考虑到您使用 CalendarEvents 的方式,这肯定会改变
old_events = user.getEvents(); //DB fetch
old_events.addAll(new_events);
Set<CalendarEvent> set_event = new HashSet<CalendarEvent>(old_events);
在这里,您会受到错误的哈希码和等于的影响。您尝试过滤一组独特的事件。但是该集合将仅保留具有唯一 eventDateTime 的事件。考虑到在您的代码中,您在集合中添加了 2 次相同的元素,它们中的大多数将具有相同的 id。
在坚持的后期,JPA 不会期望这种情况发生。
推荐阅读
- javascript - 使用 forEach 过滤 JSON 对象
- python - 使用一列中的多个值过滤数据框中的值
- google-app-engine - APP Engine:OAuth 客户端被删除?
- react-native - 如何解决 assembleRelease 上的 react-native-immediate-phone-call 错误
- flutter - 当 defaultRender 设置为非常基本的 ArcRendererConfig() 时,Flutter GoogleChart 饼图不呈现
- javascript - 如何将javascript变量添加到html标签
- google-chrome - 如何修复我的jsp页面中变为(¤)的美元符号($)?
- css - Hexo markdown + bulma css
- android - 属性 android:shortcutLongLabel 未找到
- vba - 如何使用 VBA 代码创建查找消息类的搜索文件夹?