Java JPA 一起保存主外键

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19424179/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 17:02:06  来源:igfitidea点击:

JPA saving primary and foreign key together

javahibernatejpa

提问by Spark-Beginner

I have two Entities DealEntityand DealTypeEntityand they are related as-

我有两个实体DealEntityDealTypeEntity与它们相关的原样

@Entity
class DealEntity{
  @ManyToOne(fetch = FetchType.EAGER)
  @JoinColumn(name = "DEAL_TYPE_ID")
  private DealTypeEntity dealTypeEntity;
}

I am trying to save by creating instance of DealEntity which contains DealTypeEntity ref.

我试图通过创建包含 DealTypeEntity ref 的 DealEntity 实例来保存。

I am using JPA and it giving me exception in entityManager.persist(entity)

我正在使用 JPA,它给了我例外 entityManager.persist(entity)

     Oct 17, 2013 3:36:34 PM org.apache.catalina.core.StandardWrapperValve invoke
     SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path             [/Travel-Portal] threw exception [Request processing failed; nested exception is          org.springframework.dao.InvalidDataAccessApiUsageException:org.hibernate.TransientPropertyV alueException: object references an unsaved transient instance - save the transient  instance before flushing: training.impetus.tp.model.DealEntity.dealTypeEntity ->  training.impetus.tp.model.DealTypeEntity; nested exception is  java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object  references an unsaved transient instance - save the transient instance before flushing:  training.impetus.tp.model.DealEntity.dealTypeEntity ->  training.impetus.tp.model.DealTypeEntity] with root cause
 org.hibernate.TransientPropertyValueException: object references an unsaved transient i nstance - save the transient instance before flushing:  training.impetus.tp.model.DealEntity.dealTypeEntity ->  training.impetus.tp.model.DealTypeEntity
    at org.hibernate.engine.spi.CascadingAction.noCascade(CascadingAction.java:380)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:176)
    at o rg.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEv entListener.java:160)
    at o  rg.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlus hingEventListener.java:151)
    at o    rg.hiborg.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:151)
    at org.hib

采纳答案by SubOptimal

Either you do what the error message propose "save the transient instance before flushing"

要么按照错误消息的建议“在刷新前保存瞬态实例”

entityManager.persist(dealTypeEntity);
entityManager.persist(dealEntity);

or you could change the annotation in DealEntity to

或者您可以将 DealEntity 中的注释更改为

@ManyToOne(fetch = FetchType.EAGER, cascade=CascadeType.PERSIST)
// then persisting DealEntity would persist the childs also
entityManager.persist(dealEntity);

回答by Lyju I Edwinson

There is another scenario where we can get the same error, We had this same issue when we manually inserted an entry with update_count column as null value. So we had a member table that relates to fund table. We inserted a new fund manually and forgot to put a value for update_count. When the application created a member with this fund we got this exception while saving the member data org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing:. We are using update_count column for version control [@version].

在另一种情况下,我们可能会遇到相同的错误,当我们手动插入一个带有 update_count 列的条目为空值时,我们遇到了同样的问题。所以我们有一个与基金表相关的成员表。我们手动插入了一个新基金,但忘记为 update_count 设置一个值。当应用程序用这个基金创建一个成员时,我们在保存成员数据时遇到了这个异常org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing:。我们正在使用 update_count 列进行版本控制 [@version]。

回答by Jayen Chondigara

instead of passing reference object passed the saved object, below is explanation which solve my issue,

而不是传递引用对象传递保存的对象,下面是解决我的问题的解释,

//wrong

//错误的

entityManager.persist(dealTypeEntity);

entityManager.persist(dealTypeEntity);

dealEntity.setDealType(dealTypeEntity);

dealEntity.setDealType(dealTypeEntity);

entityManager.persist(dealEntity)

entityManager.persist(dealEntity)

//right

//对

DealTypeEntity savedEntity= entityManager.persist(dealTypeEntity);

DealTypeEntity savedEntity= entityManager.persist(dealTypeEntity);

dealEntity.setDealType(savedEntity);

dealEntity.setDealType(savedEntity);

entityManager.persist(dealEntity)

entityManager.persist(dealEntity)