Каскад гибернации сохраняет родителя и детей - родительский ключ не найден - PullRequest
2 голосов
/ 21 февраля 2011

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

В родительском классе (Product.java)

@OneToMany(mappedBy="product",
        fetch=FetchType.EAGER,
        cascade={CascadeType.ALL})
public Set<Picture> getPictures() {
        return pictures;
}

@Transient
public void addPicture(Picture picture) {
    picture.setProduct(this);
    pictures.add(picture);
}

В детском классе (Picture.java)

@ManyToOne(cascade={CascadeType.ALL})
@JoinColumn(name="lse09lse06id")
public Product getProduct() {
        return product;
}

"lse09lse06id" - это столбец внешнего ключа в таблице дочерних объектов.

В моем классе контроллера:

Product product = new Product();
.... (set properties of product)
Picture newPicture = new Picture();
.... (set properties of newPicture)
product.addPicture(newPicture);
productService.addProduct(product);

В моем классе ProductService:

@Override
@Transactional
public void addProduct(Product product) {
    productDAO.addProduct(product);
}

В моем классе ProductDAO:

@Override
public void addProduct(Product product) {
    product.setDateCreated(new Date());
    sessionFactory.getCurrentSession().save(product);
}

Исключение, генерируемое при выполнении кода контроллера:

org.springframework.web.util.NestedServletException: Ошибка обработки запроса; вложенными исключение org.springframework.dao.DataIntegrityViolationException: Не удалось выполнить пакетное обновление JDBC; SQL [вставить в lse09pictures (lse09content, lse09date_created, lse09date_deleted, lse09date_updated, lse09is_deleted, lse09lse06id, lse09id) значения (?,?,?,?,?,?, ?)]; ограничение [CSSE3005GG.LSE09PICTURES_FK]; вложенными исключение org.hibernate.exception.ConstraintViolationException: Не удалось выполнить пакетное обновление JDBC

Одно из вложенных исключений:

java.sql.BatchUpdateException: ORA-02291: ограничение целостности (CSSE3005GG.LSE09PICTURES_FK) нарушено - родительский ключ не найден

Любая помощь будет высоко ценится. Эта проблема действительно противна. Спасибо!

Ответы [ 2 ]

0 голосов
/ 20 октября 2018

Использование классов Hibernate Cascade

  • org.hibernate.annotations.Cascade
  • org.hibernate.annotations.CascadeType

Не могли бы вы попробоватьпереписать это так:

@OneToMany(fetch=FetchType.EAGER,
@Cascade(value = { CascadeType.SAVE_UPDATE, CascadeType.PERSIST,
     CascadeType.MERGE })
public Set<Picture> getPictures() {
    return pictures;
}

И

@ManyToOne
@Cascade(value = { CascadeType.SAVE_UPDATE, CascadeType.PERSIST,
     CascadeType.MERGE })
@JoinColumn(name="lse09lse06id")
public Product getProduct() {
    return product;
}

После этого вызов Hibernate.saveOrUpdate должен делать то, что вы хотите.

Cyberax прав, циклические ссылки могут сбивать с толку для Hibernate.Кроме того, каскадное удаление следует использовать с осторожностью, поэтому я использовал только «Сохранить», «Сохранить» и «Объединить».

0 голосов
/ 22 февраля 2011

Удалить cascade из @ManyToOne(cascade={CascadeType.ALL}). Hibernate запутывается в циклических ссылках.

Либо сохраните экземпляр Product (явно вызвав для него session.save ()) перед экземпляром Picture.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...