官术网_书友最值得收藏!

Step 4: Creating a data access object

Now to the key part, where we will mix the knowledge we learned in  Chapter 2, Dependency Injection Using CDI 2.0, to use persistence APIs. As you may know, any data access layer includes what's called data access objects; those objects are responsible for performing basic data housekeeping operations such as inserting, retrieving, modifying, and deleting rows from the database.

To do this in JPA, we have to first obtain an instance of the persistence provider object that implements the fundamental JPA EntityManager interface. To obtain such an object, the following code is used:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa-examplesPU"); 
EntityManager em = emf.createEntityManager(); 

Using CDI, we can just inject an instance of the entity manager without all the hassle of manually obtaining that instance shown in the previous code excerpt; this is achieved using the @PersistenceContext annotation, which is equivalent to the @Inject annotation discussed in the previous chapter, but is different in that it's used specifically for entity managers and is passed the persistence unit name as shown in the following code:

@RequestScoped 
public class MovieBean { 
 
    @PersistenceContext(name = "jpa-examplesPU") 
    private EntityManager entityManager; 
 
} 

Now, let's define an insert method that is used to insert a movie entity into the database:

@RequestScoped 
@Transactional 
public class MovieBean { 
 
    @PersistenceContext(name = "jpa-examplesPU") 
    private EntityManager entityManager; 
 
    public void insert(Movie movie) { 
        entityManager.persist(movie); 
    } 
 
} 

As you see, we have called the persist method, passing a movie instance, which will be inserted as a row in the database. Other entity managers methods and features will be discussed in future sections in greater detail.

But, what's the role of the @Transactional attribute? The @Transactional attribute defines an interceptor (remember this concept from the previous chapter?) which automates entity transactions on all the methods in the annotated bean. As mentioned earlier in the architecture section, all database transactions should be performed within the boundaries of an entity transaction. To do this programmatically, the following code should be written:

entityManager.getTransaction().begin(); 
entityManager.persist(movie); 
entityManager.getTransaction().commit(); 

If you are familiar with database transactions, there should be no problem with the previous code. We should start an active transaction before performing any database update operations, and at the end, we should commit out transaction. This is a very important concept in relational databases in order to keep the integrity of your data when performing a multi-step database operation, so that either all operations complete successfully upon reaching the commit statement, or nothing is applied at all if it failed to reach the commit statement as an exception occurred.

The transactional attribute on your CDI bean automates the previous code excerpt. You will never need to begin or commit your transactions, as all methods in a @Transactional bean will run within the boundary of an entity transaction. Moreover, if a @Transactional bean method calls other methods with nested database operations, all the database operations of the original or submethods will execute within the boundary of the same transaction. Transaction propagation is one of the most important features required in any enterprise application, and is achieved using the @Transactional attribute with zero code.

Now, let's write a servlet and a JSP to test our code:

@WebServlet(urlPatterns = "/add-movie") 
public class AddMovieServlet extends HttpServlet{ 
 
    @Inject 
    private MovieBean movieBean; 
     
    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        String movieTitle = request.getParameter("movie_title"); 
         
        Movie movie = new Movie(); 
        movie.setTitle(movieTitle); 
         
        movieBean.insert(movie); 
         
    } 
     
} 


Here is the JSP to test the code:

<html> 
    <head> 
        <title>Add a New Movie</title> 
        <meta charset="UTF-8"> 
    </head> 
    <body> 
        <h1>Add a New Movie</h1> 
        <form action="./add-movie" method="POST"> 
            Title: <input name="movie_title" type="text"/><br/> 
            <input type="submit" value="Add"/> 
        </form> 
    </body> 
</html> 

Run the JSP; the following page should be displayed:

Now, write a title, click Add, and then refer to the database. Your new entity should have been added successfully.

Congratulations! You have just written your first JPA application. In the following sections, we are going to study JPA in great detail.

主站蜘蛛池模板: 石楼县| 孟村| 广州市| 璧山县| 滁州市| 祁连县| 五莲县| 荃湾区| 滕州市| 马尔康县| 洛川县| 翁牛特旗| 荆门市| 深水埗区| 沁源县| 宜黄县| 香格里拉县| 德化县| 威海市| 江陵县| 桂林市| 喀喇| 景宁| 玛纳斯县| 浏阳市| 广宁县| 郴州市| 鄂尔多斯市| 都江堰市| 马关县| 通城县| 清流县| 沙田区| 乃东县| 鹤峰县| 唐海县| 湄潭县| 耒阳市| 泗洪县| 安徽省| 耿马|