使用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
当前回答
在引入乐观锁定(@Version)之后,我对所有PUT HTTP事务都面临同样的错误
在更新实体时,必须发送该实体的id和版本。如果任何实体字段与其他实体相关,那么对于该字段,我们也应该提供id和版本值,而不是JPA首先将相关实体作为新实体持久化
示例:我们有两个实体-->Vehicle(id、Car、version);汽车(id、版本、品牌);要更新/保存车辆实体,请确保车辆实体中的“车辆”字段已提供id和版本字段
其他回答
我在持久化一个实体时遇到了这种情况,在该实体中,数据库中的现有记录对于用@Version注释的字段具有NULL值(用于乐观锁定)。将数据库中的NULL值更新为0已更正此问题。
案例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();
.
.
在我的例子中,这是由于双向关系的@ManyToOne一侧没有CascadeType导致的。更准确地说,我在@OneToMany端有CascadeType.ALL,而在@ManyToOne端没有。将CascadeType.ALL添加到@ManyToOne解决了该问题。一对多:
@OneToMany(cascade = CascadeType.ALL, mappedBy="globalConfig", orphanRemoval = true)
private Set<GlobalConfigScope>gcScopeSet;
多对一(导致问题)
@ManyToOne
@JoinColumn(name="global_config_id")
private GlobalConfig globalConfig;
多对一(通过添加CascadeType.PERSIST修复)
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name="global_config_id")
private GlobalConfig globalConfig;
当我在标记为@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);
}
为了解决这个问题,我在创建新实体之前执行了查询。
在我的例子中,当我试图使用对具有空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