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

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.

主站蜘蛛池模板: 闵行区| 江津市| 化隆| 宜兰市| 临高县| 卢湾区| 甘孜县| 沛县| 浮梁县| 曲松县| 旺苍县| 呼和浩特市| 拜城县| 建水县| 云林县| 德惠市| 三河市| 蒙山县| 修武县| 湖口县| 涟水县| 乐陵市| 拜城县| 青川县| 宜黄县| 讷河市| 天镇县| 越西县| 绍兴县| 澳门| 岐山县| 信宜市| 神池县| 马山县| 大关县| 新营市| 合作市| 天镇县| 淮安市| 闽侯县| 元朗区|