使用Hibernate保存对象时收到以下错误
object references an unsaved transient instance - save the transient instance before flushing
使用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在保存父对象时将它们保存到数据库中。