TransientObjectException: объект ссылается на несохраненный переходный экземпляр — сохраните переходный экземпляр перед очисткой

Я знаю, что этот вопрос задавали много раз, но я не смог найти подходящий ответ.

У меня есть два объекта в приложении Spring Roo, которые находятся в отношениях «многие ко многим», «Выпуск» и «Компонент».

Сначала я получаю экземпляр существующего Release через

selectedRelease = Release.findReleasesByReleaseNumberEquals(version).getSingleResult();

Приведенный выше метод представляет собой сгенерированный Roo искатель, который выглядит следующим образом:

public static TypedQuery<Release> Release.findReleasesByReleaseNummerEquals(String releaseNumber) {
    EntityManager em = Release.entityManager();
    TypedQuery<Release> q = em.createQuery("SELECT o FROM Release AS o WHERE LOWER(o.releaseNumber) LIKE LOWER(:releaseNummer)", Release.class);
    q.setParameter("releaseNumber", releaseNumber);
    return q;
}

Затем я создаю новый экземпляр компонента и пытаюсь назначить его выбранному релизу.

Component component = new Component();

Set<Release> releases = new HashSet<Release>();
releases.add(selectedRelease);

component.setReleases(releases);
component.persist();

При попытке выполнить persist() я получаю исключение:

TransientObjectException: объект ссылается на несохраненный переходный экземпляр — сохраните переходный экземпляр перед сбросом: com.Release;

У кого-нибудь есть совет по этой проблеме?

Отображения выглядят следующим образом:

Релиз.java:

@ManyToMany(cascade = CascadeType.PERSIST, mappedBy = "releases")
private Set<Component> components = new HashSet<Component>();

Компонент.java

@ManyToMany(cascade=CascadeType.PERSIST)
private Set<Release> releases = new HashSet<Release>();

person Hedge    schedule 03.03.2012    source источник
comment
можете ли вы опубликовать сопоставление выпуска и компонента?   -  person ManuPK    schedule 04.03.2012
comment
Я решил проблему, выполнив persist() перед setReleases()   -  person Hedge    schedule 05.03.2012


Ответы (1)


Сообщение ясно: вы пытаетесь сохранить объект, компонент, который ссылается на другой объект, который еще не был сохранен, selectedRelease.

Решение кажется простым: просто сохраните (и сбросьте всякий раз, когда вы хотите, чтобы изменения были переданы в базу данных) объекты Release перед сохранением компонента.

Однако JPA позволяет избежать всех этих предложений с помощью TRANSITIVE PERSISTENCE, то есть параметров каскада в аннотациях @...ToMany.

Просто предупреждение на случай, если у вас двунаправленные отношения, когда у вас есть атрибут mappedBy в одной из ассоциаций @...ToMany. В этом случае вам понадобится удобный способ управления ассоциацией, то есть установка обеих сторон ассоциации.

Например, addRelease(Release r) в Component, который одновременно добавляет выпуск в набор компонентов и устанавливает для компонента (фактически экземпляр this) выпуск, переданный в качестве параметра.

person jbbarquero    schedule 04.03.2012
comment
Спасибо за ваше предложение. Я добавил cascade=CascadeType.PERSIST к обеим сторонам сопоставления, но это все равно не работает. Может ли это быть потому, что у меня нет способа управлять ассоциацией? Можете ли вы привести пример? - person Hedge; 05.03.2012