在这段代码中,我保存了主对象和该对象的外键。 我打印出“实体”和“事物”,它们应该是完全相同的对象。但他们不是。为什么?
thingList.forEach(entity -> {
System.out.println(entity);
// Save if the foreign key exists and isn't already saved in the database
if(entity.ForeignKey() != null && ForeignKeyRepository.findOne(entity.ForeignKey().getId()) == null)
{
ForeignKeyRepository.save(entity.getForeignKey());
}
Thing thing = thingRepository.save(entity);
System.out.println(thing);
});
最佳答案
如果实体不是新的,并且在 EntityManager
的 session 中已经有一个代表数据库行的不同实例,您将获得该实例,并进行修改以匹配作为参数传递的实例,如返回值。
您可以通过检查实现和相关 JPA 文档来确认这一点。
save
方法在 SimpleJpaRepository
中实现
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
em
是 EntityManager
。从它的 merge
方法文档中:
Returns: the managed instance that the state was merged to
JPA specification第 3.2.7.1 节更明确一点:
• If X is a detached entity, the state of X is copied onto a pre-existing managed entity instance X' of the same identity or a new managed copy X' of X is created.
• If X is a new entity instance, a new managed entity instance X' is created and the state of X is copied into the new managed entity instance X'.
• If X is a removed entity instance, an IllegalArgumentException will be thrown by the merge operation (or the transaction commit will fail).
• If X is a managed entity, it is ignored by the merge operation, however, the merge operation is cascaded to entities referenced by relationships from X if these relationships have been annotated with the cascade element value cascade=MERGE or cascade=ALL annotation.
关于java - Spring-data-jpa - .save() 什么时候不返回相同的实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48905294/