dierre
dierre

Reputation: 7210

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? Could it be a problem with the CascadeType?

Upvotes: 0

Views: 750

Answers (1)

awb
awb

Reputation: 324

First of all, you need to set the subscription in the channel object, which references it and the value is not nullable. 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. Hibernate does not perform any autosetting or some sort of that. So in terms of your code, adding

channel.setSubscription(subscription);

before DAO insert call should solve the issue. This way when entityManager.persist(subscription) (or however you persist) is called, the channel will be persisted too.

Upvotes: 1

Related Questions