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

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

当前回答

您应该在集合映射中包含cascade=“all”(如果使用xml)或cascade=CascadeType.all(如果使用注释)。

发生这种情况是因为实体中有一个集合,而该集合中有一项或多项不在数据库中。通过指定上述选项,您可以告诉hibernate在保存父对象时将其保存到数据库中。

其他回答

在我的例子中,当我试图使用对具有空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

当我没有持久化父对象但我正在保存孩子时,我遇到了这个异常。为了解决这个问题,在同一个会话中,我保留了子对象和父对象,并在父对象上使用了CascadeType.ALL。

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

当我在标记为@Transactional的方法中创建了一个新实体和一个关联实体,然后在保存之前执行了一个查询时,我遇到了这个问题。前任

@Transactional
public someService() {
    Entity someEntity = new Entity();
    AssocaiatedEntity associatedEntity = new AssocaitedEntity();
    someEntity.setAssociatedEntity(associatedEntity);
    associatedEntity.setEntity(someEntity);

    // Performing any query was causing hibernate to attempt to persist the new entity. It would then throw an exception
    someDao.getSomething();

    entityDao.create(someEntity);
}

为了解决这个问题,我在创建新实体之前执行了查询。

不要使用Cascade.All,除非你真的需要。角色和权限具有双向manyToMany关系。那么下面的代码就可以正常工作了

    Permission p = new Permission();
    p.setName("help");
    Permission p2 = new Permission();
    p2.setName("self_info");
    p = (Permission)crudRepository.save(p); // returned p has id filled in.
    p2 = (Permission)crudRepository.save(p2); // so does p2.
    Role role = new Role();
    role.setAvailable(true);
    role.setDescription("a test role");
    role.setRole("admin");
    List<Permission> pList = new ArrayList<Permission>();
    pList.add(p);
    pList.add(p2);
    role.setPermissions(pList);
    crudRepository.save(role);

而如果对象只是一个“新”对象,那么它将抛出相同的错误。