休眠更新为空,然后尝试通过更新的列删除

Mor*_*ool 4 java hibernate jpa

我只想从数据库中删除那些未使用的属性(orphanRemoval=true)。我得到的是它首先尝试更新参考 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;
    ...
Run Code Online (Sandbox Code Playgroud)

它的孩子

    @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;
        ...
Run Code Online (Sandbox Code Playgroud)

在我获取属性列表并清除之后,然后尝试提交我得到

    ...
    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
    ...
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么 Hibernate 尝试先更新引用,然后将其删除。我能不能以某种方式阻止它。我想要的是那些没有使用的孩子(属性)必须被删除,而不仅仅是删除引用。...

小智 7

我有类似的问题。使用“ updatetable = false ”对我有用。

你可以试试下面的代码:

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


小智 2

我觉得关系有问题。您必须映射实体,而不是它们的特定列。

我建议采用以下结构:

@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;
...
Run Code Online (Sandbox Code Playgroud)

以及属性:

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

    ...

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

所引用的父实体没有显式 ID Style。Hibernate 将其解析为其实体。

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

顺便说一句:默认情况下,子实体没有确定的顺序,因此您最好使用 aSet而不是List