使用Hibernate保存对象时收到以下错误
object references an unsaved transient instance - save the transient instance before flushing
#1楼
这不是错误的唯一原因。 我刚才遇到此错误是因为我的编码出现错字错误,我相信这会设置已保存的实体的值。
X x2 = new X();
x.setXid(memberid); // Error happened here - x was a previous global entity I created earlier
Y.setX(x2);
我通过确切地找出引起错误的变量来发现错误(在本例中为String xid
)。 我用一个catch
的代码整个块中保存的实体和印刷迹线周围。
{
code block that performed the operation
} catch (Exception e) {
e.printStackTrace(); // put a break-point here and inspect the 'e'
return ERROR;
}
#2楼
我相信这可能只是重复的答案,但为了澄清@OneToMany
,我在@OneToOne
映射以及@OneToMany
上获得了此@OneToMany
。 在这两种情况下,都是我尚未添加到Parent
中的Child
对象尚未保存在数据库中的事实。 因此,当我将Child
添加到Parent
,然后保存Parent
,Hibernate将在保存Parent
抛出"object references an unsaved transient instance - save the transient instance before flushing"
消息。
添加在cascade = {CascadeType.ALL}
对Parent's
参考Child
在这两种情况下解决了这个问题。 这挽救了Child
和Parent
。
对于任何重复的回答,我们深表歉意,只是想为大家进一步澄清。
@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "performancelog_id")
public PerformanceLog getPerformanceLog() {
return performanceLog;
}
#3楼
或者,如果您想使用最小的“功能”(例如,如果您不希望级联删除)来实现所需的功能,请使用
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
...
@Cascade({CascadeType.SAVE_UPDATE})
private Set<Child> children;
#4楼
当Hibernate认为需要保存与要保存的对象关联的对象时,在保存对象时会发生这种情况。
我遇到了这个问题,不想保存对引用对象的更改,因此我希望级联类型为NONE。
诀窍是确保设置了引用对象中的ID和VERSION,以便Hibernate认为引用对象不是需要保存的新对象。 这对我有用。
浏览要保存的类中的所有关系,以计算出关联的对象(以及关联的对象的关联对象),并确保在对象树的所有对象中都设置了ID和VERSION。
#5楼
对于我来说,这是持久存在于数据库中的现有记录的带有@Version注释的字段的值为NULL的实体(用于乐观锁定)时发生的。 在数据库中将NULL值更新为0可以更正此问题。
#6楼
您应该在集合映射中包括cascade="all"
(如果使用xml)或cascade=CascadeType.ALL
(如果使用注释)。
发生这种情况是因为您的实体中有一个集合,并且该集合具有一个或多个数据库中不存在的项目。 通过指定以上选项,您可以告诉hibernate在保存其父项时将它们保存到数据库中。
#7楼
如果您的集合可以为空,请尝试: object.SetYouColection(null);
#8楼
在我的情况下,这是由于双向关系的@ManyToOne
端没有CascadeType
引起的。 更精确地说,我有CascadeType.ALL
上@OneToMany
侧,并没有它@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;
#9楼
使用时出现此错误
getSession().save(object)
但是当我使用时它没有问题
getSession().saveOrUpdate(object)
#10楼
另一个可能的原因:在我的情况下,我试图在一个全新的实体上保存孩子之前先保存孩子。
代码在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);
#11楼
要加2美分,当我不小心将null
作为ID发送时,我遇到了同样的问题。 下面的代码描述了我的情况(OP没有提及任何特定情况) 。
Employee emp = new Employee();
emp.setDept(new Dept(deptId)); // --> when deptId PKID is null, same error will be thrown
// calls to other setters...
em.persist(emp);
在这里,我将现有部门ID设置为新的员工实例,而实际上并没有首先获取部门实体,因为我不想触发另一个选择查询。
在某些情况下, deptId
PKID来自调用方法,为null
,并且出现相同的错误。
因此,请注意PK ID的null
值
#12楼
解决此问题的简单方法是保存两个实体。 首先保存子实体,然后保存父实体。 因为父实体依赖于子实体作为外键值。
下面是一对一关系的简单考试
insert into Department (name, numOfemp, Depno) values (?, ?, ?)
Hibernate: insert into Employee (SSN, dep_Depno, firstName, lastName, middleName, empno) values (?, ?, ?, ?, ?, ?)
Session session=sf.openSession();
session.beginTransaction();
session.save(dep);
session.save(emp);
#13楼
除了所有其他好的答案之外,如果您使用merge
来保留对象,并且意外忘记在父类中使用对象的合并引用,则可能会发生这种情况。 考虑下面的例子
merge(A);
B.setA(A);
persist(B);
在这种情况下,您合并A
但忘记使用A
合并对象。 要解决该问题,您必须像这样重写代码。
A=merge(A);//difference is here
B.setA(A);
persist(B);
#14楼
还有另一种可能导致此错误进入休眠状态的可能性。 您可以将对象A
的未保存引用设置为附加的实体B
并希望保留对象C
即使在这种情况下,您也会收到上述错误。
#15楼
除非确实需要, Cascade.All
请不要使用Cascade.All
。 Role
和Permission
具有双向的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);
而如果对象只是一个“新”对象,那么它将抛出相同的错误。
#16楼
错误的可能原因之一是父实体的值的设置不存在; 例如,对于部门与雇员的关系,您必须编写此代码才能解决错误:
Department dept = (Department)session.load(Department.class, dept_code); // dept_code is from the jsp form which you get in the controller with @RequestParam String department
employee.setDepartment(dept);
#17楼
此错误的可能性很大,添加页面或编辑页面上也有其他可能性。 以我为例,我试图保存一个对象AdvanceSalary。 问题在于,在编辑中AdvanceSalary employee.employee_id为null,因为在编辑时未设置employee.employee_id。 我有一个隐藏字段并进行设置。 我的代码工作正常。
@Entity(name = "ic_advance_salary")
@Table(name = "ic_advance_salary")
public class AdvanceSalary extends BaseDO{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "employee_id", nullable = false)
private Employee employee;
@Column(name = "employee_id", insertable=false, updatable=false)
@NotNull(message="Please enter employee Id")
private Long employee_id;
@Column(name = "advance_date")
@DateTimeFormat(pattern = "dd-MMM-yyyy")
@NotNull(message="Please enter advance date")
private Date advance_date;
@Column(name = "amount")
@NotNull(message="Please enter Paid Amount")
private Double amount;
@Column(name = "cheque_date")
@DateTimeFormat(pattern = "dd-MMM-yyyy")
private Date cheque_date;
@Column(name = "cheque_no")
private String cheque_no;
@Column(name = "remarks")
private String remarks;
public AdvanceSalary() {
}
public AdvanceSalary(Integer advance_salary_id) {
this.id = advance_salary_id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public Long getEmployee_id() {
return employee_id;
}
public void setEmployee_id(Long employee_id) {
this.employee_id = employee_id;
}
}
#18楼
如果您使用的是Spring Data JPA,则在服务实现中添加@Transactional
批注即可解决该问题。
#19楼
当我不保留父对象但我正在保存孩子时,我遇到了此异常。 为了解决该问题,在同一会话中,我同时保留了子对象和父对象,并在父对象上使用了CascadeType.ALL。
#20楼
为了完整性:A
org.hibernate.TransientPropertyValueException
带消息
object references an unsaved transient instance - save the transient instance before flushing
当您尝试持久/合并一个实体并引用另一个碰巧分离的实体时,也会发生这种情况。
#21楼
我认为是因为您已尝试持久保存一个具有对另一个尚未持久的对象的引用的对象,因此它尝试在“ DB端”中对不存在的行进行引用
#22楼
情况1:当我尝试创建一个父对象并将该父对象引用保存到其子对象,然后再进行其他一些DELETE / UPDATE查询(JPQL)时,遇到了此异常。 因此,在创建父对象和使用相同父引用创建子对象之后,我只需flush()新创建的实体。 它为我工作。
情况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;
.
.
}
在上述具有OneToOne关系的parent(Reference)和child(ReferenceAdditionalDetails)的情况下,当您尝试创建Reference实体然后创建其child(ReferenceAdditionalDetails)时,它将给您相同的例外。 因此,为避免发生异常,您必须为子类设置null,然后创建父类。(示例代码)
.
.
reference.setRefAddDetails(null);
reference = referenceDao.create(reference);
entityManager.flush();
.
.
#23楼
我也面临同样的情况。 通过在属性上方设置以下注释,可以解决提示的异常。
我遇到的例外。
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在保存父对象的同时将它们保存到数据库。
#24楼
当我在标记为@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);
}
为了解决这个问题,我在创建新实体之前执行了查询。