#java #hibernate #jpa-2.0
#java #гибернация #jpa-2.0
Вопрос:
У меня есть эти два компонента:
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;
//...
}
и
public class OutputChannel {
//...
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "ID_SUBSCRIPTION", nullable = false)
private AgentSubscription subscription;
//...
}
Если мы попытаемся использовать этот метод:
@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());
}
}
Мы получаем это исключение:
javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.domain.agent.beans.channel.OutputChannel.subscription
Не должен ли гибернация сохранять подписку перед каналом? Может ли это быть проблемой с CascadeType?
Ответ №1:
Прежде всего, вам нужно установить subscription
в channel
объекте, который ссылается на него, и значение не обнуляется. Это является причиной исключения, которое вы получили. Этот тип сопоставления создает AgentSubscription
внешний ключ в OutputChannel
таблице, поэтому вам всегда нужно его устанавливать, каскадный или нет. Hibernate не выполняет никакой автоматической настройки или что-то в этом роде. Итак, с точки зрения вашего кода, добавление
channel.setSubscription(subscription);
перед вызовом DAO insert проблема должна быть решена. Таким образом, когда entityManager.persist(subscription)
вызывается (или как бы вы ни сохранялись), channel
он также будет сохранен.