Using the JPA repository

Asked

Viewed 4,977 times

4

Last Saturday I presented my TCC in college and saw that I need to improve the presented project. The system receives tax notes in format XML and manipulates them. I based the system on the company where I work. We use Primefaces, JSF, Spring Ioc, Hibernate.

I then started reading some things searched in Google, left me maybe confused, but I will inform what I understood.

The repository would be a class to search for information in the database or at the location where the information was persisted. But in the case of JpaRepository it provides the link to a certain class of Model with possibility to persist in the database.

I am correct?

I read that this implementation is a good one because the DAO is abstracted by ORM of JPA. Then there would be no need to implement a class DAO.

I would like the idea of colleagues to know what is right to think and what is wrong.

And if using the interface JpaRepository is it possible to make an abstract class to then extend my implemented classes as a repository? And work together with the service?

Would have some example code or link?

2 answers

7


In general you are correct.

Repository Pattern

Repository is a design pattern similar to DAO (Data Access Object) in the sense that its goal is to abstract access to data in a generic way from its model. The difference is that the Repository seeks to represent the data as a collection of elements, even remembering a Collection.

Spring Data Jpa

The Spring Data Jpa project facilitates implementation of the standard Repository through AOP (Aspect Oriented Programming - aspect-oriented programming).

Using only one interface, Spring will dynamically "generate" the implementation of data access methods. Extend the interface JpaRepository is optional, but the advantage is it already comes with several of generic CRUD methods and you don’t need to reset them all.

At first it might be a little weird to use this Spring project. Who does not know AOP and how Spring Data works will waste time looking for the implementation of interfaces.

Creating new methods simply via signatures is very easy. See this example:

@Repository
public interface ClienteRepository extends JpaRepository<Cliente, Long> {
    Cliente findByNome(String nome);
    Page<Cliente> findByCidadeAndEstado(Cidade cidade, Estado, estado, Pageable pageable);
}

At first we can ask: what does Spring do with it?

First the prefix findBy in the names of the methods means that it will be a query method.

What comes next is as an expression that defines which attributes will be used as filters. In the first example, findByNome, means, search by attribute nome using the value passed in the first parameter. In the second example, the generated query will use an expression with the operator AND considering the attributes cidade and estado.

In addition, the special parameter of the type Pageable says the result will be paged. Note that the return method is a "customer page".

See the documentation on cherishing for more details.

Alternatively, you can specify any JPA or native query through the @Query annotation. See documentation.

Example of JPA query:

public interface UserRepository extends JpaRepository<User, Long> {

  @Query("select u from User u where u.firstname like %?1")
  List<User> findByFirstnameEndsWith(String firstname);

}

Example of native query:

public interface UserRepository extends JpaRepository<User, Long> {
  @Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?0", nativeQuery = true)
  User findByEmailAddress(String emailAddress);
}

Customizing the Spring Data Jpa

There are basically two ways to further customize the Spring Data JPA:

Creating a specific implementation

If for only one case you really need to make an implementation of methods, it is possible. For this, if you have an interface ClienteRepository:

  1. Create an interface ClienteRepositoryCustom with the methods you want to implement.
  2. Create a class in the same package ClienteRepositoryImpl implementing this interface.
  3. Interface ClienteRepository extend the interface ClienteRepositoryCustom

See the documentation.

Creating a "generic interface"

If you have methods that you want to have in all repositories, but that are not present in the interface JpaRepository, you can create a generic interface with these methods and have your repositories extend this interface.

Replacing the Jparepository implementation

Well, all magic has a trick behind the scenes. There is, yes, an implementation of all this and you can extend it conforms your goals.

I myself did this in a recent project to allow a dynamic search using a map, where each map entry is automatically added to the search clauses.

I believe that describing the whole process is outside the scope of the answer, as well as greatly lengthening the content. So I’m going to leave the link to one of the articles I used to make the implementation is Customizing Spring Data JPA Repository.

On the one hand, create your extended version of JpaRepository it’s not very complicated, but I suggest you try to address specific issues using the more specific approaches already mentioned. Think twice before creating or overwriting methods that affect all your classes.

  • thanks for your reply, but during a reading a doubt caught my attention even of other material I read, in the material said that automatically the Spring would implement the methods for me through the class attributes, correct? If yes, in my example does not occur.

  • @Macario1983 I did not understand what you meant by "in my example does not occur". Anyway, just to clarify, if you have a JPA entity Cliente with an attribute String nome and create a signature Cliente findByNome(String nome);, Spring Data Jpa can create a query like this: select c from Cliente c where nome = :nome.

  • @Macario1983 but you only see it at the time of execution.

  • in my example, would be the test code in Eclipse , as I was seeing in this tutorial, if I didn’t get it wrong, automatically by the attributes of the model class would be created search methods (findBy) with each attribute of the class, therefore my comment. http://www.baeldung.com/2011/12/the-persistence-layer-with-spring-data-jpa/

  • 1

    @Macario1983 No, that’s not what happens. Spring does not automatically create methods for cadas attribute, because that would be a great waste. It creates methods according to the signatures that are in the interaface. What is described in the last topic of my answer is that I created a generic search method based on a map. If the map has the input nome = "José" or idade = 30, then the query would have the following filter: where nome like 'José%' and idade = 30. However, I had to do this implementation manually.

  • and you implement without DAO? And how good it brings you from your implementation?

  • 1

    In the project I mentioned, I don’t have the DAO layer. The layers are: Controller (JSF Managedbeans), Service (spring Beans business rules) and Repository (Spring repositories). A great advantage of Repository is not to waste time implementing each DAO method (which is most often a copy of each other). This prevents a developer from introducing incorrect database access logic (forgetting to close connections, setting incorrect parameters, etc.). However, the same effect could be achieved by creating generic Daos, which you extend and get the implementation of basic methods.

  • @Macario1983 I forgot to quote you in the previous comment.

  • The link you passed the author does a few more things that gets really complicated so that this starting to understand, some statements of objects in the class, but it turns out that the EntityManager plays the role of HibernateSessionFactory that we created right? This kind of approach as it stands in relation to the pattern OpenSessionInView? Or this pattern should use Spring’s own?

  • @Macario1983 O EntityManager is equivalent to HibernateSession, but that is part of the JPA specification and the other is specific to Hibernate. In general, for new implementations, it is better to use JPA standard. That doesn’t change much about OpenSessionInView, but this is a pattern unsaved. I always try to wear something like Session per request (a session/entitymanager/connection per request.

  • I ask you about the pattern you wear instead of the OSIV because while I created the TCC program, using as a basis the company system, I saw that at all times it was called the class Open Session In View, and I had another problem, that the transactions were opened at the request level HTTP, because I say this, because my program had as purpose either the user insert a collection of files or the files downloaded directly from the server e-mail, when the transaction was taking place at the level of e-mail from the system, that this function was automated, transaction was not initialized.

  • In fact, EntityManager is equivalent to Session of Hibernate, while a EntityManagerFactory of JPA is equivalent to SessionFactory hibernate.

  • @Roger That’s right. Thanks for the correction.

Show 8 more comments

4

To DAO is a design pattern that abstracts the data persistence. A Repository is an abstraction of a collection of objects and their respective methods of handling. Both can exist in the same project. The crack DAO, Repository and DTO (Data Transfer Object) can be considered a Work Unit (Unit of Work).

A formal definition of DAO has on the Oracle website, in English: http://www.oracle.com/technetwork/java/dataaccessobject-138824.html. A translator can help.

A general overview of JPA repository can be found here: http://workingonbits.com/2011/05/05/effective-pattern-for-data-access-with-jpa/.

The JPA Repository is a special implementation of Repository, but note that the Repository is concerned with exposing methods that manipulate collections, not operations in databases such as DAO. In the case of the JPA Spring Repository, it proposes to do some things automatically (search, insert, update), but still the focus is the manipulation of items in a collection.

It may even be that the concepts get confused because there are people who implement a Repository with a DAO face (for example, putting a method called Update() in the Repository). Correct, in the case of a fully integrated repository with a database, would be for the repository to update this transparently.

  • Well, it’s expensive, but what I had read was that the DAO would not need to exist since we agree, if the ORM does these functions there would be no why, what I found strange but looking at Javadoc is to say that the repository can not do the DAO function but be added to it, and I see persistence methods in the JPA interface , I liked because there is one to save in bulk . In this example even addresses more to the side that you emphasize in the comments, but as I do not know much I found strange the use of DTO.

  • That is correct. A repository is aggregated to a DAO because the technological implementation of processing with the database is in the DAO, and what the repository needs for interaction with the database it calls for by the DAO.

  • It seems to be more interesting to implement it, and make persistence methods, such as saving, insert and delete in the service, but only doing the treatment for example deletion of objects that do not have the correct id.

  • I can’t see this conceptual difference between DAO and Repository. To me, they are the same thing in practice, even if the creator of the "Repository" has tried to give a more "abstract" definition in terms of collections. All Daos I’ve seen have exactly the same types of methods as a Repository, namely methods like "findById", "findAll", "findByName", "save", "persist", "remove", etc. What’s the difference?

  • @Rogério The difference is at what level is abstraction. In DAO there is the technological approach (for example, SQL sentences are written in DAO). In the Repository there is no such minutiae. There is only the method and how it acts on the collection. The technological detail (SQL, for example) is expected to be solved in another layer of the application.

  • Repository implementations also include data access code (including SQL sentences if JDBC is used). I checked in the book DDD (from the creator of "Repository"), and he says nothing against it, and does not say that one should solve the technological "detail" in another layer. For me, the distinction is only in the way of describing the idea, but the idea is the same, ie DAO = Repository.

  • I’ve seen it, and she’s wrong, unfortunately, despite all the upvotes. You who think DAO is different from Repository should be able to give a concrete example, where something is done in a DAO that cannot (or should not) be done in a Repository, or vice versa. But I can’t find anything in that direction.

  • @Roger If you are wrong, I return the burden: can you prove by reliable source that you are wrong? Also I can not find anything in this sense.

  • How am I going to prove that something (in this case, the essential difference between DAO and Repository) does not exist? You may have read that proving the non-existence of something is a fallacy (http://www.logicallyfallacious.com/index.php/logical-fallacies/146-proving-non-existence). However, I would be satisfied if you could indicate where (page, paragraph) in the DDD book makes this supposed difference (there is a PDF of the book here: http://www-public.int-evry.fr/~Gibson/Teaching/CSC7322/Readingmaterial/Evans03.pdf).

Show 5 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.