简体   繁体   English

为了保存与JPA和Hibernate的OneToMany关系

[英]Order to save OneToMany relationship with JPA and Hibernate

I have these two beans: 我有以下两种豆:

public class AgentSubscription {

//...
  @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, mappedBy = "subscription")
  @Fetch(FetchMode.SUBSELECT)
  @OrderBy("ID_SUBSCRIPTION")
  private List<OutputChannel> channels;
//...
}

and

public class OutputChannel {
//...
  @ManyToOne(fetch = FetchType.EAGER)
  @JoinColumn(name = "ID_SUBSCRIPTION", nullable = false)
  private AgentSubscription subscription;
//...
}

If we try to use this method: 如果我们尝试使用此方法:

  @Transactional
  public void addChannel(AgentSubscription subscription, OutputChannel channel)
  {
    try
    {
      List<OutputChannel> channels = new ArrayList<OutputChannel>();
      channels.add(channel);
      subscription.setChannels(channels);
      subscription = agentSubscriptionDao.insert(subscription);
    }
    catch (Exception e)
    {
      LOGGER.error("Unable to add channel to subscription " + subscription.getSubscriptionId());
    }
  }

We get this exception: 我们得到以下异常:

javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.domain.agent.beans.channel.OutputChannel.subscription

Shouldn't Hibernate save the subscription before the channel? Hibernate是否应该在频道之前保存订阅? Could it be a problem with the CascadeType? CascadeType可能有问题吗?

First of all, you need to set the subscription in the channel object, which references it and the value is not nullable. 首先,您需要在channel对象中设置subscription ,该subscription对象引用该subscription ,并且该值不可为空。 That is the cause of the exception you recieved. 这就是您收到异常的原因。 This type of mapping creates AgentSubscription foreign key in the OutputChannel table, so you always have to set it, cascading or not. 这种类型的映射会在OutputChannel表中创建AgentSubscription外键,因此您始终必须设置它(是否层叠)。 Hibernate does not perform any autosetting or some sort of that. Hibernate不执行任何自动设置或某种方式。 So in terms of your code, adding 因此,就您的代码而言,添加

channel.setSubscription(subscription);

before DAO insert call should solve the issue. 在DAO插入呼叫之前应该可以解决该问题。 This way when entityManager.persist(subscription) (or however you persist) is called, the channel will be persisted too. 这样,当调用entityManager.persist(subscription) (或无论您是否坚持)时, channel也将被坚持。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM