2016-07-25 2 views
1

я получил следующую двунаправленную связь между двумя классами сущностей:Cascade удалить с Spring Data JPA (двунаправленной)

пользователя

@Entity 
@Table(name = "USER") 
public class User { 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user") 
    @Cascade({CascadeType.REMOVE, CascadeType.SAVE_UPDATE}) 
    private Set<Book> books; 
} 

Книга

@Entity 
@Table(name = "BOOKS") 
public class Book { 
    @ManyToOne(optional = false) 
    @JoinColumns({ 
      @JoinColumn(name = "ID", referencedColumnName = "ID"), 
      @JoinColumn(name = "NAME", referencedColumnName = "NAME"), 
    }) 
    private User user; 

}

Я хочу, чтобы удалить User с удалением каскадирования до всех книг, связанных с пользователем. Однако, когда я использовал Spring Data CrudRepository:

myDAO.delete(String userId) // interface extending CrudRepository<User, UserPK> 

Я получаю:

Caused by: org.hsqldb.HsqlException: integrity constraint violation: foreign key no action; FK_IN88FEHUXOOYQK0YE71USPIEP table: USER 

Я пытался использовать orhpanRemoval, все виды CascadeTypes как org.hibernate и javax.persistence. Я не хочу реализовывать собственные запросы, такие как @Query(Delete from User....). Мне интересно, что из-за инструкции исключения внешний ключ без каких-либо действий ли я напрямую указывал параметр каскада.

+0

Как создается схема базы данных? Почему у вас есть '@Cascade (CascadeType.REMOVE)' от 'Book' до' User'?Конечно, вы не хотите удалять всех '' '' '' '' '' '' '' '' '' '' '' '', когда вы удаляете эту книгу (или вы), потому что это то, что будет делать этот каскад. – manish

+0

Привет @manish, я удалил каскад из Книги, все равно ничего не изменилось. что касается схемы, я не использую ни один из sql-скриптов, я создаю LocalContainerEntityManagerFactoryBean с флагом «hibernate.hbm2ddl.auto», который настроен на «обновление». – ServerSideCat

ответ

0

От Book до User есть отношения «один-к-одному». Поэтому для таблицы Book требуется только один столбец для захвата внешнего ключа в таблицу User.

Код:

@ManyToOne(optional = false) 
@JoinColumns({ 
     @JoinColumn(name = "ID", referencedColumnName = "ID"), 
     @JoinColumn(name = "NAME", referencedColumnName = "NAME"), 
}) 
private User user; 

должно быть просто:

@ManyToOne(optional = false) 
@JoinColumn(name = "user_id") 
private User user; 

При использовании схемы Generation Tool гибернации (HBM2DDL), ограничения внешних ключей генерируются следующим образом:

ALTER TABLE 
    BOOK 
ADD CONSTRAINT 
    FK_IN88FEHUXOOYQK0YE71USPIEP 
FOREIGN KEY 
    (USER_ID) REFERENCES USER (ID) 
ON UPDATE NO ACTION 
ON DELETE NO ACTION; 

Notice ON DELETE NO ACTION. Это означает, что при удалении экземпляра User ничего не должно произойти с Book экземплярами, связанными с ним (NO ACTION). Это практически означает, что нельзя удалять User.

Если вы хотите Book экземпляров, связанных с User быть удалено, когда User удаляется, DDL должен быть:

ALTER TABLE 
    BOOK 
ADD CONSTRAINT 
    FK_IN88FEHUXOOYQK0YE71USPIEP 
FOREIGN KEY 
    (USER_ID) REFERENCES USER (ID) 
ON UPDATE NO ACTION 
ON DELETE CASCADE; 

Это может быть сгенерировано путем добавления Hibernate специфичной аннотации к модели предметной области:

class User { 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user") 
    @Cascade({CascadeType.REMOVE, CascadeType.SAVE_UPDATE}) 
    @OnDelete(OnDeleteAction.CASCADE) 
    private Set<Book> books; 
} 
Смежные вопросы