Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate does perform an update rather than a delete operation when a child entity gets removed

I have two entites, the parent (item) which has a list of history entities, when I remove a old row from the child list (histories) item.getHistories().remove(0) I would expect that hibernate performs a delete operation on the child row, but hibernate updates the foreign key to null. This update causes a NOT NULL VIOLATION hence the foreign key has a NOT NULL constraint.

This is my parent entity:

@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "item", schema = "public", catalog = "foo")
public class RepricingItem extends BaseDatesEntity {

    @Id
    @SequenceGenerator(name="item_id_seq", sequenceName = "item_id_seq", allocationSize = 5)
    @GeneratedValue(strategy = SEQUENCE, generator = "item_id_seq")
    @Column(name = "id", unique = true, insertable = true, updatable = false, nullable = false)
    protected Long id;

    @Size(min = 1, max = 100)
    @Column(name = "title", nullable = false, insertable = true, updatable = true)
    private String title;

    @OneToMany(fetch = LAZY, cascade = ALL, orphanRemoval = true)
    @JoinColumn(name = "item_id")
    private List<ItemHistory> histories;
}

And this is the child:

@Data
@EqualsAndHashCode(callSuper=true)
@Entity
@Table(name = "item_history", schema = "public", catalog = "foo")
public class RepricingItemBuyBoxHistory extends BaseEntity {

    @ManyToOne(fetch = LAZY, optional = false)
    @JoinColumn(name = "item_id", nullable = false, updatable = false)
    private RepricingItem repricingItem;

    @Size(min = 1, max = 255)
    @Column(name = "some_history_data", nullable = false, insertable = true, updatable = false)
    private String someHistoryData;
}

This is the history table with the not null constraint:

CREATE TABLE "item_history" (
    id                BIGSERIAL PRIMARY KEY,
    item_id           BIGINT                      NOT NULL REFERENCES "item" (id) ON DELETE CASCADE,
    inserted          TIMESTAMP WITHOUT TIME ZONE,
    updated           TIMESTAMP WITHOUT TIME ZONE,
    some_history_data VARCHAR(255)                NOT NULL
) WITH (OIDS =FALSE);

This is the update clause generated by hibernate:

11:17:00,794 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] SQL Error: 0, SQLState: 23502
11:17:00,794 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] Batch entry 0 update foo.public.item_history set item_id=null where item_id=903372 and id=245 was aborted.  Call getNextException to see the cause.

How can I tell hibernate to delete the child rather than trying to remove the relation.

like image 848
PeterPan Avatar asked Jan 18 '26 04:01

PeterPan


1 Answers

I think that you need to add a 'mappedBy' attribute to your @OneToMany annotation in RepricingItem. Something like this, I think:

@OneToMany(fetch = LAZY, cascade = ALL, orphanRemoval = true, mappedBy = "repricingItem")
@JoinColumn(name = "item_id")
private List<ItemHistory> histories;

The problem has to do with which entity is the 'owner'. A better explanation than I can give can be found here: inverse = “true” example and explanation

like image 60
Christopher Avatar answered Jan 20 '26 19:01

Christopher



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!