Reputation: 7210
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
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