2017-01-05 3 views
1

Я думал, что до недавнего времени я лучше разбирался в Spring Data JPA (удаляет).Весенние данные Удаление JPA не то, что я ожидал

Во всяком случае, у меня есть два класса с OneToMany и ManyToOne отношения:

@Entity 
@Table(name = "COMPANIES") 
public class Company implements Serializable { 
... 
     @OneToMany(mappedBy = "company", 
        fetch = FetchType.EAGER, 
        orphanRemoval = true, 
        cascade = CascadeType.ALL) 
     private Set<Commodity> commodities = new HashSet<>(); 
} 

.... 

@Entity 
@Table(name = "COMMODITIES") 
public class Commodity implements Serializable { 
... 
     @ManyToOne(optional = false) 
     @JoinColumn(name = "COMPANY_ID", referencedColumnName = "ID", nullable = false) 
     private Company company; 
} 

Я хочу, чтобы удалить Commodity запись поэтому у меня есть это в моем слое службы:

@Transactional 
public void delete(Commodity commodity) { 
    repo.delete(commodity); 
} 

Когда я запустить код, он выполняет все SELECT, но на самом деле никогда не выполняет удаление. Нет сообщений об ошибках ... не удалять в журналах и т.д.

Так я обнаружил, что есть два варианта:

1) Снимите CascadeType.ALL

2) Измените мой метод удаления для:

@Transactional 
public void delete(Commodity commodity) { 
    Company company = commodity.getCompany(); 
    company.getCommodities().remove(commodity); 
    companyRepo.save(company); 
} 

3) Напишите собственный метод @Query для выполнения удаления (а не).

Мое понимание каскадирования заключалось в том, что если бы мы должны были удалить основную запись, например, Company, то все ее дочерние объекты будут автоматически удалены. Это имеет смысл для меня.

Итак, мой вопрос: почему этот CascadeType препятствует ручному удалению дочерней записи?

Благодаря

EDIT

Я не очень ясно. Использование опции 1 или опции 2 выше выполняет удаление.

+0

См. Следующее, хотя кажется, что поведение, возможно, изменилось, если исключить исключение, чтобы ничего не делать. Самый верный ответ - это ваше решение (2), которое является лучшим решением независимо от того, как вы гарантируете, что ваша модель в памяти остается совместимой с базой данных, что не соответствует вашему оригинальному решению. http://stackoverflow.com/questions/11649249/deleted-object-would-be-re-saved-by-cascade-remove-deleted-object-from-associat –

ответ

2

Это по дизайну.

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

Вот точная цитата из спящего режима doc:

С другой стороны, если объект удаляется из коллекции (один-ко-многим или многие-ко-многим ассоциации), он не будет удаляется по умолчанию. Это поведение полностью согласовано; изменение внутреннего состояния другой объект не должно приводить к исчезновению связанного объекта. Аналогично, добавление сущности в коллекцию не приводит к тому, что объект станет постоянным, по умолчанию.

+0

Это то, что я обнаружил с трудом. К счастью, я не потратил слишком много времени на это. :-) – cbmeeks

0

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

В противном случае взгляните на question 306144; Надеюсь, поможет. Дополнительная информация: here

+0

Нет, удалены разрешены. – cbmeeks

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