28 November, 2013

Spring-boot JPA sample with auto-configured repository

Spring-boot allows to create a completely minimalistic applications.
For example, its auto-configuration ability raises and configures JPA and Hibernate-related stuff:
DataSource, Entity and Transaction Managers, Repositories.
With no manual configuration in your code or in xml files.

And the application code is getting smaller and smaller...

User.java
package sb; 
 
import javax.persistence.*; 
 
@Entity 
@Table(name = "sb_user") 
public class User { 
 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    public long id; 
    public String name; 
    public String alias; 
 
    public User() { 
    } 
 
    public User(long id, String name) {
        this.id = id; 
        this.name = name; 
    } 
} 
UserRepository.java
package sb;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {

    @Query("SELECT u FROM User u WHERE u.alias IS NOT NULL")
    List<User> findAliased();
} 
UserController.java
package sb;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("user")
public class UserController {
    protected final Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private UserRepository users;

    @RequestMapping("test")
    public String test() {
        log.info("Test");
        return "OK";
    }

    @RequestMapping("user")
    public User getUser(@RequestParam("id") long id) {
        log.info("Get user");
        return users.findOne(id);
    }

    @RequestMapping("users")
    public List<User> getUsers(@RequestParam("ids") List<Long> ids) {
    log.info("Get users");
        return users.findAll(ids);
    }

    @RequestMapping("aliased")
    public List<User> getAliasedUsers() {
    log.info("Get aliased users");
        return users.findAliased();
    }
} 
Application.java
package sb;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@EnableAutoConfiguration
@Configuration
@ComponentScan
public class Application {

    public static void main(String[] args) throws Throwable {
        new SpringApplication(Application.class).run(args);
    }
} 
application.properties
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://srv0/test
spring.datasource.username=test
spring.datasource.password=test 
schema.sql
-- DROP TABLE sb_user;

CREATE TABLE sb_user
(
  id   SERIAL PRIMARY KEY    NOT NULL,
  name CHARACTER VARYING(65) NOT NULL,
  alias CHARACTER VARYING(20)
);

INSERT INTO sb_user (name) VALUES ('Ben Linus');
INSERT INTO sb_user (name) VALUES ('Claire Littleton');
INSERT INTO sb_user (name) VALUES ('Desmond Hume');
INSERT INTO sb_user (name) VALUES ('Frank Lapidus');
INSERT INTO sb_user (name, alias) VALUES ('Hugo Reyes', 'Hurley');
INSERT INTO sb_user (name) VALUES ('Jack Shephard');
INSERT INTO sb_user (name, alias) VALUES ('James Ford', 'Sawyer');
INSERT INTO sb_user (name) VALUES ('Jin-Soo Kwon');
INSERT INTO sb_user (name) VALUES ('Miles Straume');
INSERT INTO sb_user (name) VALUES ('Richard Alpert');
INSERT INTO sb_user (name) VALUES ('Sayid Jarrah');
INSERT INTO sb_user (name) VALUES ('Sun-Hwa Kwon');



Build and run command: gradle clean build runJar

Test urls:
http://localhost:8080/user/user?id=2
http://localhost:8080/user/users?ids=1,3,5,7
http://localhost:8080/user/aliased

5 comments:

xiaonan309 said...

Hello, I use your sample, but I get exception as bellow.
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [dao.UserRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1103)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
... 16 more

xiaonan309 said...

hello,
I got exception as bellow:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [dao.UserRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Help!! :)

Corneliu Ene said...

Foarte tare. Mersi mult pentru postarea asta!

Pablo said...

Thank you! I was looking for.

Unknown said...

How to do the same with 2 different databases ?????
what changes need to be done in above code?????