To build the monolith, we need to perform the following steps:
- First, we need the entities that will represent the data kept by the application. Here is the User entity:
@Entity
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String name;
@Column
private String email;
public User(){
}
public User(String name, String email) {
this.name = name;
this.email = email;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
- Here is the UserAddress entity:
@Entity
public class UserAddress implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
@ManyToOne
private User user;
@Column
private String street;
@Column
private String number;
@Column
private String city;
@Column
private String zip;
public UserAddress(){
}
public UserAddress(User user, String street, String number,
String city, String zip) {
this.user = user;
this.street = street;
this.number = number;
this.city = city;
this.zip = zip;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
}
- Now we define one bean to deal with the transaction over each entity. Here is the UserBean class:
@Stateless
public class UserBean {
@PersistenceContext
private EntityManager em;
public void add(User user) {
em.persist(user);
}
public void remove(User user) {
em.remove(user);
}
public void update(User user) {
em.merge(user);
}
public User findById(Long id) {
return em.find(User.class, id);
}
public List<User> get() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> pet = cq.from(User.class);
cq.select(pet);
TypedQuery<User> q = em.createQuery(cq);
return q.getResultList();
}
}
- Here is the UserAddressBean class:
@Stateless
public class UserAddressBean {
@PersistenceContext
private EntityManager em;
public void add(UserAddress address){
em.persist(address);
}
public void remove(UserAddress address){
em.remove(address);
}
public void update(UserAddress address){
em.merge(address);
}
public UserAddress findById(Long id){
return em.find(UserAddress.class, id);
}
public List<UserAddress> get() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<UserAddress> cq = cb.createQuery(UserAddress.class);
Root<UserAddress> pet = cq.from(UserAddress.class);
cq.select(pet);
TypedQuery<UserAddress> q = em.createQuery(cq);
return q.getResultList();
}
}
- Finally, we build two services to perform the communication between the client and the beans. Here is the UserService class:
@Path("userService")
public class UserService {
@EJB
private UserBean userBean;
@GET
@Path("findById/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response findById(@PathParam("id") Long id){
return Response.ok(userBean.findById(id)).build();
}
@GET
@Path("get")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response get(){
return Response.ok(userBean.get()).build();
}
@POST
@Path("add")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response add(User user){
userBean.add(user);
return Response.accepted().build();
}
@DELETE
@Path("remove/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response remove(@PathParam("id") Long id){
userBean.remove(userBean.findById(id));
return Response.accepted().build();
}
}
- Here is the UserAddressService class:
@Path("userAddressService")
public class UserAddressService {
@EJB
private UserAddressBean userAddressBean;
@GET
@Path("findById/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response findById(@PathParam("id") Long id){
return Response.ok(userAddressBean.findById(id)).build();
}
@GET
@Path("get")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response get(){
return Response.ok(userAddressBean.get()).build();
}
@POST
@Path("add")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response add(UserAddress address){
userAddressBean.add(address);
return Response.accepted().build();
}
@DELETE
@Path("remove/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response remove(@PathParam("id") Long id){
userAddressBean.remove(userAddressBean.findById(id));
return Response.accepted().build();
}
}
Now let's break the monolith down!