- @HyperResource auto-generates events 📨
- @Observes required to catch events 🕵️♂️
- Built on CDI Event Bus ⚡
@Entity
@HyperResource(
path = "/orders",
events = @Events(
onCreate = true, // Auto CREATE events
onUpdate = true, // Auto UPDATE events
onDelete = true // Auto DELETE events
onPatch = true, // Auto PATCH events
emitter = OrderEvents.class // Custom emitter
)
)
public class Order extends BaseEntity {
// entity fields...
}The OrderEvents must be defined by the user to handle the events emitted by the Order entity.
@ApplicationScoped
public class OrderEvents extends AbstractTypedEmitter<Order> {
protected OrderEvents() {
super(Order.class);
}
@Override
protected void emitTyped(EntityEvent.Type type, Order entity) {
switch (type){
case CREATE -> postCreate(entity);
case UPDATE -> postUpdate(entity);
case DELETE -> postDelete(entity);
case PATCH -> postPatch(entity);
}
}
void postCreate(Order Order) {
System.out.println("Post-create processing for Order: " + Order.getOrderNumber());
// Add any additional logic needed after the event is emitted
}
void postUpdate(Order Order) {
System.out.println("Post-update processing for Order: " + Order.getOrderNumber());
// Add any additional logic needed after the event is emitted
}
void postDelete(Order Order) {
System.out.println("Post-delete processing for deleted Order");
// Add any additional logic needed after the event is emitted
}
void postPatch(Order Order) {
System.out.println("Post-patch processing for Order: " + Order.getOrderNumber());
// Add any additional logic needed after the event is emitted
}
}// User-defined observer (catch all events)
@ApplicationScoped
public class GlobalEventLogger {
public void logAllEvents(@Observes EntityEvent<?> event) {
System.out.printf("[GLOBAL] %s %s%n",
event.getType(),
event.getEntity().getClass().getSimpleName());
}
}
// User-defined observer (specific entity)
@ApplicationScoped
public class OrderEventProcessor {
public void handleOrderEvent(@Observes EntityEvent<Order> event) {
switch(event.getType()) {
case CREATE -> processNewOrder(event.getEntity());
case UPDATE -> processOrderUpdate(event.getEntity());
case DELETE -> processOrderRemoval(event.getEntity());
}
}
// ... processing methods
}public abstract class BaseEntityService<ENTITY, DTO, MAPPER> {
@Inject
protected Event<EntityEvent<ENTITY>> eventBus;
protected void fireEvent(EntityEvent.Type type, ENTITY entity) {
eventBus.fire(new EntityEvent(type, entity));
}
}| Event | Types | Requires Config |
|---|---|---|
| CREATE | post-persist | onCreate=true |
| UPDATE | post-merge | onUpdate=true |
| DELETE | post-remove | onDelete=true |
// Narrow observation
@Observes EntityEvent<SpecificEntity>
// Broad observation
@Observes EntityEvent<?>public void safeObserver(@Observes EntityEvent<?> event) {
try {
// processing logic
} catch (Exception e) {
log.error("Event processing failed", e);
}
}- Async Processing:
public void asyncProcessing(@ObservesAsync EntityEvent<Order> event) {
// Long-running task
}| Event | Types | Requires Config |
|---|---|---|
| CREATE | post-persist | onCreate=true |
| UPDATE | post-merge | onUpdate=true |
| DELETE | post-remove | onDelete=true |
⚠️ Important: Events will be silently ignored if no observer exists for them. Always verify your observers are properly registered in CDI context.