1

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

Malakai
  • 3,011
  • 9
  • 35
  • 49
Iraponti
  • 95
  • 2
  • 3
  • 10
  • 2
    You should have a look at Spring Boot. You will not need these CRUD methods. https://spring.io/guides/gs/accessing-data-jpa/ – Simon Martinelli Dec 27 '17 at 15:39
  • Even if you don't use Spring Boot, you should use spring data jpa. And even if you don't, you definitely need to read the Spring documentation on Data access, and JPA integration: https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html. Reading the documentation is part of the job. It will save you tons of time in the long run. – JB Nizet Dec 27 '17 at 15:44

3 Answers3

2

If you are using spring Boot then you don't need entity manager. All you need to do is to define Datasource in you properties file. And create a Bean in our Configuration class just like:

@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource datasource() {
    return DataSourceBuilder.create().build();
}

Now rest of the things you can handle with repositories.They will be like:

import org.springframework.data.repository.CrudRepository;

public interface RuleRepository extends CrudRepository<Rule, Long>  {

}

In your controllers you will use it like:

@Autowired
private RuleRepository ruleRepository;

@Get
@Path("/getRule/:id")
public Rule find(@PathParam("id")Long id){
    return ruleRepository.findOne(id);
}

These dependencies I used in my gradle project. You will find Maven version for same:

compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile group: 'mysql', name: 'mysql-connector-java'
Jayesh Choudhary
  • 748
  • 2
  • 12
  • 30
2

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.

shinjw
  • 3,329
  • 3
  • 21
  • 42
  • I hava one more question, in my methods controller, do I have to return the associated view or the ModelMap ? (The view can acces to the ModelMap if I don't return it ?) Because I don't know if it's a good way to let the controller guess which view he is referring to. – Iraponti Dec 29 '17 at 13:14
  • This would probably warrant another question. – shinjw Dec 29 '17 at 21:10
0

You definitely need to have a look on Spring Boot(http://start.spring.io), it allows easier to start web app development. As for persistence layer you could use Spring Data JPA(already includes Hibernate) module which also can be easily integrated with Spring Boot. The beauty of Spring Data that is already have written by default most queries like save(), remove(), find() and so on. You only need to define Objects which will be used by Spring Data.

Update: See my Spring Boot REST API example here

Malakai
  • 3,011
  • 9
  • 35
  • 49