2013-04-10 2 views
4

я следующее соотношениеJPA: ограничение внешнего ключа при удалении

Class UserAccount{ 
//Other fields 
@OneToMany(mappedBy = "userAccount", cascade = CascadeType.REMOVE) 
private Set<Images> imagesShared; 

@ManyToMany 
@JoinTable(name = "USER_LIKES", joinColumns = @JoinColumn(name = "USER_NAME"), inverseJoinColumns = @JoinColumn(name = "ID")) 
private Set<Images> imagesLiked; 
} 

Class Images{ 
//other fields 
@ManyToMany(mappedBy = "imagesLiked") 
private Set<UserAccount> likes; 
} 

я получаю исключение после этих строк

Hibernate: delete from IMAGES where ID=? 
Hibernate: delete from COMMENTS where COMMENT_ID=? 
Hibernate: delete from COMMENTS where COMMENT_ID=? 
Hibernate: delete from COMMENTS where COMMENT_ID=? 
Hibernate: delete from COMMENTS where COMMENT_ID=? 
Hibernate: delete from COMMENTS where COMMENT_ID=? 
Hibernate: delete from IMAGES where ID=? 

Исключение:

Cannot delete or update a parent row: a foreign key constraint fails (`testdb`.`USER_LIKES`, CONSTRAINT `FKC6704E28B4E3D8B` FOREIGN KEY (`ID`) REFERENCES `IMAGES` (`ID`)) 

В моем понимании это происходит когда JPA пытается удалить imagesShared. Я попытался сделать это:

for (Images image : userAccount.getImagesShared()){ 
      image.setLikes(null); 
     } 
em.remove(account); 

Но ту же ошибку. Кто угодно?

UPDATE

Когда я добавляю эту линию он работает отлично.

for (Images image : userAccount.getImagesShared()){ 
      image.setLikes(null); 
     } 
userAccount.getImagesShared().clear(); 
em.remove(account); 

Но в чем разница между операцией удаления, которую выполняет JPA, и чем я занимаюсь?

+0

Попробуйте опорожнение коллекции вместо того, чтобы его недействительным в цикле: image.getLikes() пустой() – dcernahoschi

+0

Да, я пробовал, но не делает. help – shazinltc

ответ

6

Один из ваших private Set<Images> imagesShared или private Set<Images> imagesLiked должен иметь ссылку на изображение, которое вы пытаетесь удалить.

Перед тем, как удалить его, вам нужно будет пройти все и удалить ссылку на изображение.

EDIT:

Чтобы ответить на ваш второй вопрос.

for (Images image : userAccount.getImagesShared()){ 
      image.setLikes(null); 
     } 
userAccount.getImagesShared().clear(); 
em.remove(account); 

работает, потому что вы клиринговые ссылки изображения, сохраненные в userAccount по телефону userAccount.getImagesShared().clear()

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

+0

Да, я делаю это, очищая коллекцию. – shazinltc

+0

Итак, что я понимаю, вам нужно очистить всю ссылку на изображение в объекте UserAccount до того, как каскадное удаление будет действовать на объект изображения? – shazinltc

+0

Каскад работает сверху вниз ... Если ваше изображение ссылается на UserAccount, оно не будет удалено только потому, что вы удаляете изображение. Если вы удалите userAccount, тогда он удалит подэлементы в нем, если нет других ссылок. – Thihara

0

private Set<Images> imagesLiked имеет внешний ключ ссылку на IMAGES (ID), так что если вы пытаетесь удалить private Set<Images> imagesShared; без удаления private Set<Images> imagesLiked;.

Так попробуйте удалить imagesLinked также

image.setImagesLinked(null); 
+0

Я делаю это .. – shazinltc

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