no

How to Convert JPA to CDI Events

Learn how to convert JPA to CDI events. This is typically used in observer pattern when you want to do something after an operation has been...

Learn how to convert JPA to CDI events. This is typically used in observer pattern when you want to do something after an operation has been done on an entity. For example, you want to send an email or initiate an HTTP request after an entity has been created.

1. Introduction

To demonstrate this functionality a JakartaEE project will be created using maven's wildfly-jakartaee-webapp-archetype archetype that will have one entity Book. Entity create, update, and delete operations will be observed.

*Lombok will be used to automatically generates getters and setters.

2. Entity Listener, Entity, and Service

Entity Listener - this component is responsible for listening to JPA events and converting them to CDI.

public class EntityListener {

	@Inject
	@Created
	protected Event<Object> entityCreatedEventProducer;

	@Inject
	@Updated
	protected Event<Oobject> entityUpdatedEventProducer;

	@Inject
	@Removed
	protected Event<Oobject> entityRemovedEventProducer;

	@PrePersist
	public void created(Object d) {
		entityCreatedEventProducer.fire(d);
	}

	@PreUpdate
	public void updated(Object d) {
		entityUpdatedEventProducer.fire(d);
	}

	@PreRemove
	public void removed(Object d) {
		entityRemovedEventProducer.fire(d);
	}
}
Book Entity - this is a classic book entity example. Note that I'm using Lombok to generate getters and setters
@Entity
@Data
@EntityListeners(EntityListener.class)
public class Book {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	private String name;
}
Book Service - again nothing extraordinary here
public class BookService {

	@PersistenceContext
	private EntityManager em;

	public void create(Book book) {
		em.persist(book);
	}

	public Book update(Book book) {
		return em.merge(book);
	}

	public void delete(Book book) {
		em.remove(book);
	}

	public void flush() {
		em.flush();
	}
}

3. Event Objects

The event interfaces can be defined based on requirements. Here, 3 events are created for create, update, and remove.

Let's see an example for create:

@Qualifier
@Target({ METHOD, FIELD, PARAMETER, TYPE })
@Retention(RUNTIME)
public @interface Created {

}

4. Event Listener

EntityEventObserver - This class listens to CDI events. One can argue, why not just put these codes in the entity listener? In some cases that is enough. For example, if you just want to set a field in the entity during an update like updateAt. But it's not recommended for cases wherein the observer needs to perform complex tasks and depends on several services.

@ApplicationScoped
public class EntityEventObserver {

	private Logger log = Logger.getLogger(EntityEventObserver.class);

	public void onCreate(@Observes @Created Object e) {
		log.info("created " + e);
	}

	public void onUpdate(@Observes @Updated Object e) {
		log.info("updated " + e);
	}

	public void onRemove(@Observes @Removed Object e) {
		log.info("removed " + e);
	}
}

5. Testing the Application

To test the events, a test class is created to perform create, update, and remove entity database operations. This is performed in the StartupListener class.

@Singleton
@Startup
public class StartupListener {

	private Logger log = Logger.getLogger(StartupListener.class);

	@Inject
	private BookService bookService;

	@PostConstruct
	public void createUpdateRemove() {
		log.info("Running tests. Check the logs...");

		Book book = new Book();

		book.setName("Mahouka Koukou");
		bookService.create(book);

		book.setName("Gate Jietai");
		book = bookService.update(book);
		// commit the update
		bookService.flush();

		bookService.delete(book);
	}
}

To run this project, you must have docker installed on your local machine.

5.1 Run Wildfly in docker with the following command:
>docker run --name wildfly_21 -p 8080:8080 -p 9990:9990 -it jboss/wildfly:21.0.1.Final /opt/jboss/wildfly/bin/standalone.sh -b 0.0.0.0 -bmanagement 0.0.0.0

5.2 Set the Wildfly admin and password by running WILDFLY_HOME/bin/add-user.bat.
>docker exec -it wildfly_21 /opt/jboss/wildfly/bin/add-user.sh

With the following choices:

  • Type of user: Management User
  • User: admin
  • Details of new user: a. Update the existing user and password and roles
  • Password: admin
  • Group: Admin
5.3 Deploy and run this application in Wildfly using maven (must be executed in the project's root directory):
>mvn install wildfly:deploy

It will prompt for username and password. Enter admin/admin.

Check the log in Wildfly and you should see the observer logs.




5.4 To undeploy the application run:
>mvn wildfly:undeploy

6. References:

Related

coding 467280306182925612

Post a Comment Default Comments

item