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

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

当前回答

当我在标记为@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);
}

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

其他回答

另一个可能的原因是:在我的案例中,我试图在一个全新的实体上,先救孩子,再救父母。

User.java模型中的代码如下:

this.lastName = lastName;
this.isAdmin = isAdmin;
this.accountStatus = "Active";
this.setNewPassword(password);
this.timeJoin = new Date();
create();

setNewPassword()方法创建PasswordHistory记录,并将其添加到User中的历史记录集合中。由于尚未为父级执行create()语句,因此它试图保存到尚未创建的实体集合中。我所要做的就是在调用create()之后移动setNewPassword()调用。

this.lastName = lastName;
this.isAdmin = isAdmin;
this.accountStatus = "Active";
this.timeJoin = new Date();
create();
this.setNewPassword(password);

案例1:当我试图创建一个父级并将该父级引用保存到其子级,然后再保存其他DELETE/UPDATE查询(JPQL)时,我遇到了这个异常。所以我只在创建父实体之后和使用相同的父引用创建子实体之后,刷新()新创建的实体。这对我有用。

案例2:

父类

public class Reference implements Serializable {

    @Id
    @Column(precision=20, scale=0)
    private BigInteger id;

    @Temporal(TemporalType.TIMESTAMP)
    private Date modifiedOn;

    @OneToOne(mappedBy="reference")
    private ReferenceAdditionalDetails refAddDetails;
    . 
    .
    .
}

子类:

public class ReferenceAdditionalDetails implements Serializable{

    private static final long serialVersionUID = 1L;

    @Id
    @OneToOne
    @JoinColumn(name="reference",referencedColumnName="id")
    private Reference reference;

    private String preferedSector1;
    private String preferedSector2;
    .
    .

}

在上述情况下,父级(Reference)和子级(ReferenceAdditionalDetails)具有OneToOne关系,并且当您尝试创建Reference实体,然后创建其子级(Reference AdditionalDetails)时,它将给您提供相同的异常。因此,为了避免异常,必须为子类设置null,然后创建父类。(示例代码)

.
.
reference.setRefAddDetails(null);
reference = referenceDao.create(reference);
entityManager.flush();
.
.

不要使用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);

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

就我而言,问题完全不同。我有两节课,比如c1和c2。C1和C2之间的依赖关系是OneToMany。现在,如果我在DB中保存C1,它将抛出上述错误。

解决这个问题的方法是从消费者请求中获取第一个C2的id,然后通过存储库调用找到C2。然后将C2保存到C1对象中。现在,如果我保存C1,它可以正常工作。

我也面临同样的情况。通过在属性上方设置以下注释,可以解决提示的异常。

我面临的例外。

Exception in thread "main" java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.model.Car_OneToMany

为了克服,我使用了注释。

    @OneToMany(cascade = {CascadeType.ALL})
    @Column(name = "ListOfCarsDrivenByDriver")
    private List<Car_OneToMany> listOfCarsBeingDriven = new ArrayList<Car_OneToMany>();

Hibernate抛出异常的原因:

由于我附加到父对象的子对象此时不在数据库中,因此在控制台上引发此异常。

通过提供@OneToMany(cascade={CascadeType.ALL}),它告诉Hibernate在保存父对象时将它们保存到数据库中。