簡體   English   中英

將休眠更新為null,然后嘗試按更新的列刪除

[英]hibernate update to null, then try to delete by updated column

我只希望那些未使用的屬性將從數據庫中刪除(orphanRemoval = true)。 我得到的是它首先嘗試更新商品PRODUCT_ID,然后刪除它。 但由於Refretion是密鑰的一部分,因此不能。

上級:

    @Entity
    @Table(name = "STYLE")
    public class Style implements IterableById, Serializable {
    ...
        @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL, orphanRemoval=true)
        @JoinColumn(name="PRODUCT_ID", referencedColumnName = "PRODUCT_ID")
        private List<Attribute> attributes;
    ...

它的孩子

    @Entity
    @Table(name="ATTRIBUTE")
    public class Attribute{
        @EmbeddedId
        private Id id;
        ...

        @Embeddable
        public static class Id implements Serializable{

        private static final long serialVersionUID = -8631874888098769584L;

        @Column(name="PRODUCT_ID")
        protected Long productId;

        @Column(name="NAME")
        protected String name;

        @Column(name="COUNTRY_CODE")
        protected String countryCode;
        ...

在我獲取屬性列表並清除之后,然后嘗試提交我得到

    ...
    Hibernate: update ATTRIBUTE set PRODUCT_ID=null where PRODUCT_ID=?
    Hibernate: delete from ATTRIBUTE where COUNTRY_CODE=? and NAME=? and PRODUCT_ID=?
    javax.persistence.RollbackException: Error while committing the transaction
    Caused by: javax.persistence.OptimisticLockException: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
    ...

有誰知道為什么Hibernate首先嘗試更新引用,然后再刪除它。 我可以以某種方式阻止它。 我想要的是那些不用的子項(屬性)必須刪除,而不僅僅是剪切引用。 ...

我認為這種關系存在問題。 您必須映射實體,而不是實體的特定列。

我建議以下構造:

@Entity
@Table(name = "STYLE")
public class Style implements IterableById, Serializable {
...
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "style", cascade=CascadeType.ALL, orphanRemoval = true)
    private Set<Attribute> attributes;
...

和屬性:

@Entity
@Table(name="ATTRIBUTE")
public class Attribute{

    ...

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "PRODUCT_ID", nullable = false)
    protected Style style;
    ...

所引用的父實體Style沒有明確的ID。 Hibernate將其解析為其實體。

為什么在屬性類中使用如此復雜的ID?

順便說一句:默認情況下,子實體沒有確定性順序,因此您最好使用Set而不是List

我在Google上搜索了此問題,但沒有得到答案。 Hibernate在刪除之前發出一個更新SQL,該更新SQL嘗試將一個不可為空的列設置為null,然后發生異常。 我不知道為什么刪除之前會更新Hibernate問題。

最后,我使用自定義刪除JPQL而不是Spring Data JPA標准刪除方法。

 @Repository public interface ProductRepository extends PagingAndSortingRepository<Product, Long> { Product findByName(String name); String jpql_deleteById = "delete from Product p where p.id = :id"; @Modifying @Query(jpql_deleteById) void deleteById(@Param("id") Long id); } 

似乎我的問題與此類似:

如何將“插入='假'更新='假'”映射到也用於一對多FK的復合ID密鑰屬性上?

@JoinColumn(name =“ PRODUCT_ID”,referencedColumnName =“ PRODUCT_ID”, insertable = false,可更新= false

我有類似的問題。 使用“ updatable = false ”對我有用。

您可以嘗試以下代碼:

@OneToMany(fetch = FetchType.LAZY,  cascade=CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "PRODUCT_ID", referencedColumnName = "PRODUCT_ID", updatable = false)
private Set<Attribute> attributes

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM