Lifecycle Events

Whenever the framework interacts with a domain entity, lifecycle events are fired. These are:

  • instantiated

    through FactoryService. An event is also fired for view models

  • persisting

    an entity is about to be persisted (INSERTed) into the database

  • persisted

    an entity has just been persisted to the database

  • loaded

    an already persistent entity has just been loaded from the database

  • updating

    an already persistent entity is about to be saved (UPDATEd) to the database

  • updated

    an already persistent entity has just been saved (UPDATEd) to the database

  • removing

    an already persistent entity is about to be removed (DELETEd) from the database

The framework has a built-in event class (for each lifecycle hint) that is raised by default; for example a ObjectUpdatingEvent.Default is raised when an object is about to be updated. Subscribers subscribe through the EventBusService and can use the event to obtain a reference to the object just created.

This basic model can be influenced in a couple of ways:

  • first, it is also possible to suppress any events from being emitted using a configuration property (a different config property exists each lifecycle hook).

  • second, an element on DomainObject annotation (for each lifecycle hook) allows a different event subtype to be emitted instead

    This allows subscribers to more targeted as to the events that they subscribe to.

The framework also provides convenience "Doop" and a "Noop" event classes, that provoke these behaviours:

  • if the appropriate DomainObject' element is set to the "Doop" subclass, then this will event will be fired

    this is a convenient way of ensuring an event is fired even if the hook has been disabled globally, but without the hassle of defining a custom event type

  • if set to the "Noop" subclass, then an event will not be fired.

The table below summarises all the lifecycle hooks:

Table 1. Lifecycle events

Lifecycle event

Config property

@DomainObject override

Framework event types

created

ObjectCreatedEvent.Default
ObjectCreatedEvent.Doop
ObjectCreatedEvent.Noop

loaded

ObjectLoadedEvent.Default
ObjectLoadedEvent.Doop
ObjectLoadedEvent.Noop

persisting

ObjectPersistingEvent.Default
ObjectPersistingEvent.Doop
ObjectPersistingEvent.Noop

persisted

ObjectPersistedEvent.Default
ObjectPersistedEvent.Doop
ObjectPersistedEvent.Noop

updating

ObjectUpdatingEvent.Default
ObjectUpdatingEvent.Doop
ObjectUpdatingEvent.Noop

updated

ObjectUpdatedEvent.Default
ObjectUpdatedEvent.Doop
ObjectUpdatedEvent.Noop

removing

ObjectRemovingEvent.Default
ObjectRemovingEvent.Doop
ObjectRemovingEvent.Noop

Subscribers

Subscribers can be either coarse-grained (if they subscribe to the top-level event type):

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;

@Service
public class SomeSubscriber {
    @EventListener(ObjectCreatedEvent.class)
    public void on(ObjectCreatedEvent ev) {
        if(ev.getSource() instanceof ToDoItem) {
            ...
        }
    }
}

or can be fine-grained (by subscribing to specific event subtypes):

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;

@Service
public class SomeSubscriber {
    @EventListener(ToDoItem.ObjectCreatedEvent.class)
    public void on(ToDoItem.ObjectCreatedEvent ev) {
        ...
    }
}

Examples

created example

For example:

@DomainObjectLayout(
    createdLifecycleEvent=ToDoItem.CreatedEvent.class
)
public class ToDoItem {
    public static class CreatedEvent
        extends org.apache.causeway.applib.events.lifecycle.ObjectCreatedEvent<ToDoItem> { }
    ...
}

It’s possible to instantiate objects without firing this lifecycle; just instantiate using its regular constructor, and then use the ServiceInjector's injectServicesInto(…​) to manually inject any required domain services.

persisting example

For example:

@DomainObjectLayout(
    persistingLifecycleEvent=ToDoItem.PersistingEvent.class
)
public class ToDoItem {

    public static class PersistingEvent extends
        org.apache.causeway.applib.events.lifecycle.ObjectPersistingEvent<ToDoItem> { }

    // ...
}
persisted example

For example:

@DomainObjectLayout(
    persistedLifecycleEvent=ToDoItem.PersistedEvent.class
)
public class ToDoItem {

    public static class PersistedEvent extends
        org.apache.causeway.applib.events.lifecycle.ObjectPersistedEvent<ToDoItem> { }

    // ...
}
loaded example

For example:

@DomainObjectLayout(
    loadedLifecycleEvent=ToDoItem.LoadedEvent.class
)
public class ToDoItem {
    public static class LoadedEvent extends
        org.apache.causeway.applib.events.lifecycle.ObjectLoadedEvent<ToDoItem> { }
    ...
}
updating example

For example:

@DomainObjectLayout(
    updatingLifecycleEvent=ToDoItem.UpdatingEvent.class
)
public class ToDoItem {

    public static class UpdatingEvent extends
        org.apache.causeway.applib.events.lifecycle.ObjectUpdatingEvent<ToDoItem> { }

    // ...
}
updated example

For example:

@DomainObjectLayout(
    updatedLifecycleEvent=ToDoItem.UpdatedEvent.class
)
public class ToDoItem {

    public static class UpdatedEvent extends
        org.apache.causeway.applib.events.lifecycle.ObjectUpdatedEvent<ToDoItem> { }

    // ...
}
removing example

For example:

@DomainObjectLayout(
    removingLifecycleEvent=ToDoItem.RemovingEvent.class
)
public class ToDoItem {

    public static class RemovingEvent extends
        org.apache.causeway.applib.events.lifecycle.ObjectRemovingEvent<ToDoItem> { }

    // ...
}