Search code examples
javaspringhibernatejpaentitymanager

Spring - JPA - Hibernate how to use EntityManager


I'm trying to build REST application using following tech stack:

  • Spring
  • VueJs
  • JPA (Hibernate)

This is my first experience in writing Sping application and web app development overall.

I have 4 tables in my DataBase:

  • Language
  • Sentence
  • Rule
  • User

For example in Rule there is :

Rule create(EntityManagerFactory factory, String type, String hint, String help, Language language); 
List<Rule> readAll(EntityManagerFactory factory);
Rule readID(EntityManagerFactory factory, int id); 
void update(EntityManagerFactory factory, String type, String hint, String help, Language language);

So there is my questions:

  1. When I create Controllers for each table, I use the CRUD methods to modify (or not) my database, and I return a view for my HTML and VueJS part. But my method need an EntityManagerFactory, should I create a field in each Controllers class or this is not how I'm supposed to do ?
  2. Do I need to create a bean file and configure it or persistence.xml and pom.xml are enough?

Thanks


Solution

  • Seems like your first question can be broken up into multiple concerns.

    When I create Controllers for each table, I use the CRUD methods to modify (or not) my database, and I return a view for my HTML and VueJS part. But my method need an EntityManagerFactory, should I create a field in each Controllers class or this is not how I'm supposed to do?

    Since you have already accepted an answer that recommends the use of spring-data-jpa. You will be dealing with entities and repositories.

    Entities are JPA managed beans that will interact with your database.

    @Entity
    @Table(name = "rule")
    public class Rule {
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        long id;
        String type;
        ...
        @OneToOne
        @JoinColumn(...)
        Language language;
    }
    

    Repositories will provide all the necessary operations required to perform an action against your database. With JPA you can create an interface that extends CrudRepository which would provide you with some CRUD operations that come free with it. findOne(/* id */), delete(), save()

    @Repository
    public interface RuleRepository extends CrudRepository<Rule, Long> {
    
         // You can easily specify custom finders
         public List<Rule> findByType(String type);
    
    }
    

    But my method need an EntityManagerFactory, should I create a field in each Controllers class or this is not how I'm supposed to do?

    It's typically frowned upon to have a request/response object to be JPA entity. See the linked answer for should i use jpa entity in rest request and/or response

    There are multiple approaches that you can take to take a controller request and send a response to your client side project.

    @Controller
    public class RuleController {
        @Autowired
        private RuleRepository ruleRepository;
    
        // Approach 1: Use Request Parameters - enforce inputs
        @PostMapping("/rule/:id")
        public Rule postWithRequestParams(@PathParam("id") Long id, 
                        @RequestParam("type") String type, 
                        @RequestParam("hint") String hint, 
                        @RequestParam("languageField1") String languageField1) {
            Rule inputRule = new Rule(id, type, hint, new Language(languageField1));
    
            Rule responseRule = ruleRepository.save(inputRule);
            return responseRule; // I would imagine you would want to set up a model for the response itself
        }
    
    
    
        // Approach 2: Use RequestBody - serialize Rule from the request
        @PostMapping("/rule/:id")
        public Rule postWithRequestParams(@PathParam("id") Long id, @RequestBody Rule inputRule) {
            Rule responseRule = ruleRepository.save(inputRule);
            return responseRule;
        }
    

    Do I need to create a bean file and configure it or persistence.xml and pom.xml are enough?

    If you have added spring-boot-starter-data-jpa as a dependency, a lot of the bean configuration has already been done for you.

    In your main/src/resources (you should have an application.properties or application.yml)

    spring.datasource.url= # JDBC url of the database.
    spring.datasource.username= # Login user of the database.
    spring.datasource.password= # Login password of the database.
    

    Spring does a lot of the magic and heavy lifting for you.