2016-04-06 2 views
1

В настоящее время я использую Hibernate в проекте, и у меня возникли проблемы с настройкой отношения «Множество к многим». Я думаю, что моя проблема связана с типами Cascade.Спящий режим для многих типов каскадных типов

Сценарий: у нас есть объявление, и у каждого объявления может быть много тегов, но каждый тег может быть связан со многими рекламными объявлениями. ManyToMany аннотация рекламной сущности является:

@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH }) 
@JoinTable(name = "adMediaAdvertiserTag", 
     joinColumns = { @JoinColumn(name = "adMediaId") }, 
     inverseJoinColumns = { @JoinColumn(name = "advertiserTagId") }) 

И отображение ManyToMany на тег объекта является:

@ManyToMany(mappedBy = "advertiserTags", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }) 

Я вижу две различных ошибки в зависимости от конфигурации и типа каскада и, если тег уже существует в базе данных.

Если каскадного типа на объявлении не включает PERSIST и тег не существует, то мы получим это исключение:

TransientObjectException: object references an unsaved transient instance 

И если каскадного типа на объявлении действительно включает PERSIST и тег уже существует, мы получим:

PersistentObjectException: detached entity passed to persist 

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

Правильно ли это? Есть ли способ, с помощью которого hibernate может автоматически обрабатывать это для меня?

Дайте мне знать, если это не ясно или вам нужна дополнительная информация.

UPDATE

Я спасаю объектов с использованием сервиса, который использует метод Сохраните CrudRepository объект springframework. Существует много кода, поэтому я не могу опубликовать его полностью.

В настоящее время я не использую метод merge или persist для любого объекта, который я пытаюсь сохранить. Я был под впечатлением, что Hibernate справится с такими вещами для меня.

+0

Так вы говорите, что некоторые из тегов уже могут существовать там, где некоторые из них являются новыми и нуждаются в сохранении. Если это так, разве это не призыв к 'объединению' вместо метода' persist'? –

+0

Да, это правильно. Я пробовал это, но когда добавлен новый тег, он возвращает TransientObjectException: объект ссылается на несохраненный экземпляр переходного процесса –

+0

Вы имеете в виду CascadeType или метод, используемый для сохранения объекта? –

ответ

1

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

User user = new User(); 
Role role = new Role(); 
role.setId("TEST_ROLE"); 
user.getRoles().add(role); 

entityManager.persist(user); 

User user2 = new User(); 
user2.getRoles().add(role); 
entityManager.persist(user2); 
System.out.println(user2.getId()); 

в пользователя у меня есть:

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST) 
@JoinTable(name = "user_roles", 
     joinColumns = {@JoinColumn(name = "user_id", nullable = false, updatable = true)}, 
     inverseJoinColumns = {@JoinColumn(name = "role_id", nullable = false, updatable = true)}) 
protected List<Role> roles = new ArrayList<>(); 

и в роли у меня есть:

@ManyToMany(mappedBy="roles") 
protected List<User> users; 
+0

Спасибо за ответ, но это был один из сценариев, которые я объяснял, что не работал для сценария, когда у нас есть существующий тег (или роль в вашем случае). Я уточню вопрос с помощью некоторого контекста. –

+0

Я просто заметил вызов метода persist, это необходимо для каждого вновь созданного объекта? –

+0

Да, вы должны сделать это, чтобы сохранить нового пользователя, в этом случае, и объект Role будет сохраняться, косвенно из-за каскада. – Mustafa

Смежные вопросы