Java 休眠更新为null,然后尝试按更新列删除

Java 休眠更新为null,然后尝试按更新列删除,java,hibernate,jpa,Java,Hibernate,Jpa,我只希望那些未使用的属性将从DB中删除(orphanRemoving=true)。 我得到的是,它首先尝试更新reference PRODUCT_ID,然后删除它的。但由于引用是关键的一部分,所以它不能 家长: @Entity @Table(name = "STYLE") public class Style implements IterableById, Serializable { ... @OneToMany(fetch=FetchType

我只希望那些未使用的属性将从DB中删除(orphanRemoving=true)。 我得到的是,它首先尝试更新reference PRODUCT_ID,然后删除它的。但由于引用是关键的一部分,所以它不能

家长:

    @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;
    ...
在我获取一个属性列表并清除之后,尝试提交我得到

    ...
    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首先尝试更新引用,然后删除它吗。我能不能阻止它。我想要的是,那些没有被使用的child(属性)必须被删除,而不仅仅是删除引用。
我认为这段关系有问题。您必须映射实体,而不是它们的特定列

我建议采用以下结构:

@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;
...
引用的父实体
样式
没有显式ID。Hibernate将其解析为其实体

为什么在属性类中使用如此复杂的ID


B.T.W.:默认情况下,子实体没有确定的顺序,因此您最好使用
集合
而不是
列表

似乎我的问题与此类似:


@JoinColumn(name=“PRODUCT\u ID”,referencedColumnName=“PRODUCT\u ID”,“insertable=false,updateable=false)

我在谷歌上搜索这个问题,但没有得到答案。Hibernate在删除之前发出更新SQL,更新SQL尝试将不可为null的列设置为null,然后发生异常。我不知道为什么Hibernate会在删除之前发布更新

最后,我使用定制的deleteJPQL代替了SpringDataJPA标准的delete方法

@存储库
公共接口ProductRepository扩展了分页和排序存储库{
产品findByName(字符串名称);
字符串jpql_deleteById=“从产品p中删除,其中p.id=:id”;
@修改
@查询(jpql_deleteById)
void deleteById(@Param(“id”)Long id);

}
我也有类似的问题。使用“updateable=false”对我来说很有效

您可以尝试以下代码:

@OneToMany(fetch = FetchType.LAZY,  cascade=CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "PRODUCT_ID", referencedColumnName = "PRODUCT_ID", updatable = false)
private Set<Attribute> attributes
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,orphan=true)
@JoinColumn(name=“PRODUCT\u ID”,referencedColumnName=“PRODUCT\u ID”,updateable=false)
私有集属性

我不需要反向引用。这就是为什么我使用joincolums而不是mappedBy。此外,我不使用mappedBy,因为还有其他实体也应该能够使用属性。我已经为这个错误挣扎了很长时间。终于像个魔咒一样成功了。
@Entity
@Table(name="ATTRIBUTE")
public class Attribute{

    ...

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