Skip to main content

OnDissociate

Concepts

@org.babyfish.jimmer.sql.OnDissociate is used together with Modification/Save Command and Modification/Delete Command

  • Modification/Save Command

    Existing data structure in databaseData structure expected to be saved by user
    +-BookStore(id=2)
    |
    +-----Book(id=10)
    |
    +-----Book(id=11)
    |
    \-----Book(id=12)


    +-BookStore(id=2)
    |
    +-----Book(id=10)
    |
    |
    |
    |
    |
    \-----Book(id=9)

    This means:

    • The association between BookStore-2 and Book-10 remains unchanged

    • The association between BookStore-2 and Book-9 needs to be created

    • BookStore-2 needs to be disassociated from Book-11 and Book-12.

  • Modification/Delete Command

    This is easy to understand. Child objects need to be disassociated before deleting the parent object.

@OnDissociate can only be used on foreign key based many-to-one associations, for example:

Book.java
@Entity
public interface Book {

@Null
@ManyToOne
@OnDissociate(DissociateAction.SET_NULL)
BookStore store();
...
}
info

Although disassociation of child objects is caused by a one-to-many association (or inverse one-to-one) (that is, the parent object abandons some child objects. The one-to-many association here is BookStore.books), the disassociation mode is configured for the inverse many-to-one association (here Book.store). This design is to maintain similarity with configuring cascade properties of foreign keys in database DDLs.

For Jimmr, a one-to-many association must be bidirectional, so the many-to-one association that is the mirror image of a known one-to-many association is always known. So there is no problem with this design.

Dissociation Modes

The parameter of the OnDissociate annotation in the above code is called the dissociation mode:

There are 5 modes for dissociating child objects

NameDescription

NONE (default)

Depend on the global configuration jimmer.default-dissociate-action-checking.

LAX

This option is only valid for pseudo foreign keys (please refer to Real and Fake Foreign Keys), otherwise it will be ignored, the same as CHECK.

Dissociation operations are supported even if there are child objects. Even if the parent object is deleted (dissociation mode is also adopted by delete commands), dangling pseudo foreign keys of child objects are allowed (even if pseudo foreign keys are left dangling, the query system can still work normally).

CHECKIf there are child objects, disassociation is not supported, the operation is prevented by throwing an exception.
SET_NULL

Set the foreign key of the disassociated child object to null. The prerequisite is that the many-to-one associated propety of the child object is nullable; otherwise, attempting this configuration will lead to an exception.

DELETEDelete the disassociated child objects.

This article only introduces the configuration of OnDissociate. For how to use it further, please refer to Save Command/Dissociation Operations and Delete Commands.

Dynamic Overrides

Confiugration specified by the annotation @OnDissociate is called static configuration.

Sometimes, different businesses may have different requirements for dissociation operations. Therefore, dissociation configurations can be dynamically overridden at runtime.

  • Modification/Save Command

    sqlClient
    .getEntities()
    .saveCommand(book)
    .setDissociateAction(BookProps.STORE, DissociateAction.SET_NULL)
    .execute();
  • Modification/Delete Command

    DeleteResult result = sqlClient
    .getEntities()
    .deleteCommand(BookStore.class, 1L)
    .configure(it ->
    it
    .setDissociateAction(
    BookProps.STORE,
    DissociateAction.SET_NULL
    )
    )
    .execute();