使用Hibernate保存对象时收到以下错误

object references an unsaved transient instance - save the transient instance before flushing

当前回答

我的问题与JUnit的@BeforeEach有关。即使我保存了相关实体(在我的例子中是@ManyToOne),我也得到了同样的错误。

这个问题在某种程度上与我在父母身上的顺序有关。如果我将值赋给该属性,问题就解决了。

前任。如果我的实体问题可以有一些类别(一个或多个),并且实体问题有一个序列:

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "feedbackSeq")
@Id
private Long id;

我必须分配值问题.setId(1L);

其他回答

当Hibernate认为需要保存与正在保存的对象关联的对象时,在保存对象时会发生这种情况。

我遇到了这个问题,不想保存对引用对象的更改,所以我希望级联类型为NONE。

诀窍是确保设置了被引用对象中的ID和VERSION,这样Hibernate就不会认为被引用对象是需要保存的新对象。这对我有用。

查看要保存的类中的所有关系,以计算关联对象(以及关联对象的关联对象),并确保在对象树的所有对象中设置了ID和VERSION。

在我的例子中,当我试图使用对具有空id的实体的引用来检索相关实体时,发生了这种情况。

@Entity
public class User {
@Id
private Long id;
}

@Entity
public class Address {
@Id
private Long id;
@JoinColumn(name="user_id")
@OneToOne
private User user;
}

interface AddressRepository extends JpaRepository<Address, Long> {
Address findByUser(User user);
}

User user = new User(); // this is transient, does not have id populated
// user.setId(1L) // works fine if this is uncommented

addressRepository.findByUser(user); // throws exception

还有一种可能会在休眠状态下导致此错误。您可以将对象A的未保存引用设置为附加的实体B,并希望持久化对象C。即使在这种情况下,您也会遇到上述错误。

我相信这可能只是重复答案,但为了澄清,我在@OneToOne映射和@OneToMany上得到了这个答案。在这两种情况下,我添加到Parent的Child对象尚未保存在数据库中。因此,当我将Child添加到Parent,然后保存Parent时,Hibernate会在保存Parent之前抛出“对象引用未保存的瞬态实例-在刷新之前保存瞬态实例”消息。

在父级对子级的引用上添加cascade={CascadeType.ALL}解决了这两种情况下的问题。这保存了子对象和父对象。

很抱歉有重复的回答,只是想进一步澄清一下。

@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "performancelog_id")
public PerformanceLog getPerformanceLog() {
    return performanceLog;
}

在我的例子中,使用Cascade.ALL是在表中添加不必要的条目,表中已经有了相同的对象(生成没有id的子值就可以做到这一点)。所以我必须先从存储库中获取子对象,并将其设置为主对象,而不是导致问题的对象。

Student s = studentRepo.findByName(generatedObject.getStudent().getName())
generatedObject.student(s);