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

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.

主站蜘蛛池模板: 邮箱| 卢湾区| 利辛县| 乐都县| 三原县| 敦煌市| 琼结县| 寿宁县| 土默特左旗| 河北区| 鄱阳县| 南丹县| 临江市| 会泽县| 枞阳县| 云浮市| 岳阳县| 庆云县| 南京市| 玉溪市| 金山区| 成都市| 平潭县| 四平市| 洛扎县| 福清市| 筠连县| 古田县| 湖南省| 长阳| 山东省| 长乐市| 隆昌县| 札达县| 交城县| 思茅市| 襄汾县| 高州市| 遵义市| 长顺县| 华池县|