A persistence context is a set of managed unique entity instances, and the entity instances and their lifecycle are managed by the entity manager within the persistence context. A container-managed entity manager's lifecycle is managed by the Java EE container and an application-managed entity manager's lifecycle is managed by the application.
The entity manager for a persistence context is obtained from an entity manager factory. When container-managed entity managers are used (in Java EE environments), the application does not interact with the entity manager factory. The entity managers are obtained directly through dependency injection or from JNDI, and the container manages interaction with the entity manager factory transparently to the application. An entity manager must not be shared among multiple concurrently executing threads, as the entity manager and persistence context are not required to be threadsafe. Entity managers must only be accessed in a single-threaded manner. [JPA 2.1 Specification]
Obtaining a (container-managed) Entity Manager
The PersistenceContext annotation is used for entity manager injection with a name 'demoDB', which is a persistence-unit name specified in the persistence.xml. This is a UserService class with an entity manager injected.
@Logging @Stateless public class UserService { @Inject private Logger logger; @PersistenceContext(name="demoDB") private EntityManager em; public List<User> getAllUsers(){ Query query = em.createNamedQuery("User.findAll"); return query.getResultList(); } public User getUser(Long id){ Query query = em.createQuery("SELECT u From User u WHERE u.id = :id"); query.setParameter("id", id); User user = null; try{ user = (User)query.getSingleResult(); }catch(NoResultException ne){ logger.info(ne.getMessage() + " for an input id " + id); } return user; } }
In addition to the @PersistenceContext annotation, an interceptor @Logging annotation and an injected Logger object are also used.
User Entity Object
The UserService class uses a User entity object that maps to a 'Users' database table in a PostgreSQL database. This is a User class without the getter/setter methods to save the space. Many IDEs such as an Eclipse provide a tool to create the Entity classes after connecting to a database. This User class was also defined in the persistence.xml from the previous post.
@Entity @Table(name="users") @NamedQuery(name="User.findAll", query="SELECT u FROM User u") public class User implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="user_id_seq") @SequenceGenerator(name="user_id_seq", sequenceName="USERS_USER_ID_SEQ") @Column(name="user_id") private Long userId; @Column(name="birth_day") private Integer birthDay; @Column(name="birth_month") private Integer birthMonth; @Column(name="birth_year") private Integer birthYear; @Column(name="create_time") private Timestamp createTime; @Column(name="first_name") private String firstName; @Column(name="last_name") private String lastName; @Column(name="update_time") private Timestamp updateTime; @Column(name="user_name") private String userName;
RESTful web service
This is a web service entry point that uses the UserService. The return type is a Response abstract class in a javax.ws.rs.core package and the TomEE provides a ResponseImpl class from an Apache CXF library. Therefore, adding any additional library is not required.
@Logging @Path("/user") public class UserRestEnd { @Inject private UserService userService; @GET @Produces(MediaType.APPLICATION_JSON) public Response getAllUser(){ List<User> users = userService.getAllUsers(); Response res = Response.status(Response.Status.OK).entity(users).build(); return res; } @GET @Path("/{id}") @Produces(MediaType.APPLICATION_JSON) public Response getUser(@PathParam("id") Long id){ User user = userService.getUser(id); Response res = Response.status(Response.Status.OK).entity(user).build(); return res; } }
Start a TomEE-maven-plugin and available APIs shown on logs
mvn clean package tomee:run
When the server starts, the TomEE logs show available RESTful APIs.
org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints Service URI: http://localhost:8080/demo/user -> Pojo demo.rest.endpoint.UserRestEnd org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints GET http://localhost:8080/demo/user/ -> Response getAllUser() org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints GET http://localhost:8080/demo/user/{id} -> Response getUser(Long)
Result
Logs from the interceptor @Logging
There are no log on the UserRestEnd class and the UserService, but the @Logging annotation will create the logs with an execution time.
demo.interceptor.LoggingInterceptor.logMethod Entering demo.rest.endpoint.UserRestEnd - getAllUser demo.interceptor.LoggingInterceptor.logMethod Entering demo.rest.service.UserService - getAllUsers demo.interceptor.LoggingInterceptor.logMethod Exiting demo.rest.service.UserService - getAllUsers Execution Time: 2ms demo.interceptor.LoggingInterceptor.logMethod Exiting demo.rest.endpoint.UserRestEnd - getAllUser Execution Time: 3ms
No comments:
Post a Comment