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

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.

主站蜘蛛池模板: 三门县| 三门峡市| 张掖市| 遂溪县| 津市市| 安庆市| 青田县| 靖宇县| 利津县| 霸州市| 登封市| 台北县| 黄陵县| 台江县| 吉安市| 金沙县| 宁化县| 合阳县| 定南县| 通城县| 武宁县| 元江| 南通市| 湘乡市| 华安县| 密山市| 朝阳区| 岳西县| 招远市| 涪陵区| 微山县| 施秉县| 得荣县| 改则县| 怀集县| 昌宁县| 克拉玛依市| 左贡县| 靖远县| 曲靖市| 四川省|