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

2022-09-02 11:40:09

我有一个数据库,其中包含两个表用户和国家/地区。我想建立关系,其中许多用户可以属于一个县。我使用以下模型类使用休眠来实现这一点:

@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
}

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

  org.hibernate.HibernateException: Data was not saved: object references an unsaved transient instance - save the transient instance before flushing: com.kyrogaming.models.Country

如何解决问题?


答案 1

您无法将内容保存到 Hibernate,除非您还告诉了 Hibernate 有关此新保存对象引用的所有其他对象的信息。因此,在本例中,您正在告诉 Hibernate 有关 一个 ,但尚未告知它有关 .UserCountry

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

手动地

在保存 .session.save(country)User

级联类型

您可以向休眠指定此关系应使用 CascadeType 传播某些操作。在这种情况下,CascadeType.PERSIST将完成这项工作,CascadeType.ALL也是如此。

引用现有国家/地区

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


答案 2

看起来在“国家/地区”对象中添加的用户尚未存在于数据库中。您需要使用级联来确保在保留国家/地区时,所有不在数据中存在但与国家/地区关联的用户也会被持久化。

下面的代码应该会有所帮助:

@ManyToOne (cascade = CascadeType.ALL)
   @JoinColumn (name = "countryId")
   private Country country;

推荐