数据未保存:对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例

Mar*_*nis 16 java hibernate

我有一个包含两个表User和Country的数据库.我想要关系,许多用户可以属于一个县.我使用以下模型类使用hibernate实现它:

@Entity (name = "user")
public class User {

   @Id @GeneratedValue (strategy = GenerationType.IDENTITY)
    private int userId;
    private String username;
    private String password;

   @ManyToOne ()
   @JoinColumn (name = "countryId")
   private Country country;

    //Getter & Setter
 }


@Entity (name = "country")
public class Country {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int countryId;
    private String countryName;
   //Getter & Setter
}
Run Code Online (Sandbox Code Playgroud)

当我尝试保存用户对象时,我得到以下异常:

  org.hibernate.HibernateException: Data was not saved: object references an unsaved transient instance - save the transient instance before flushing: com.kyrogaming.models.Country
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?

sha*_*kan 25

在你告诉Hibernate关于这个新保存的对象引用的所有其他对象之前,你不能将东西保存到Hibernate.所以在这种情况下,你告诉Hibernate关于a User,但没有告诉它有关Country.

您可以通过两种方式解决此类问题.

手动

session.save(country)保存之前打电话给User.

CascadeType的

您可以指定Hibernate这个关系应该使用CascadeType传播一些操作.在这种情况下,CascadeType.PERSIST将完成这项工作,CascadeType.ALL也是如此.

参考现有国家

根据您对@zerocool的响应,您有第二个问题,即当您有两个User相同的对象时Country,您不确定它是否相同 Country.为此,您必须Country从数据库中获取相应的,在新用户上设置它,然后保存User.然后,两个User对象将引用相同的Country,而不仅仅是两个Country碰巧具有相同名称的实例.查看CriteriaAPI作为获取现有实例的一种方法.


zer*_*ool 12

看起来像您的Country对象中添加的用户看起来不在DB中.您需要使用级联来确保当国家/地区持久化时,所有不在数据中但与国家/地区相关联的用户也会被保留.

下面的代码应该有帮助

@ManyToOne (cascade = CascadeType.ALL)
   @JoinColumn (name = "countryId")
   private Country country;
Run Code Online (Sandbox Code Playgroud)


man*_*nta 7

为了增加我的 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);
Run Code Online (Sandbox Code Playgroud)

在这里,我将现有的部门 ID 设置为一个新的员工实例,而没有先实际获取部门实体,因为我不想触发另一个选择查询。

在某些情况下,deptIdPKIDnull来自调用方法,我收到相同的错误。

所以,注意nullPK ID 的值

这里给出相同的答案