Simple SpringBoot JPA Hibernate Example

In this example we will create a customer and add few orders , using OneToMany and we will see how @Version works, and if the version is increased when saving a customer with a changed order. For this we will use h2 databas, to have an example ready to run , without having to install mysql / oracle or another database .

First we need to add all dependecies to project in pom.xml :

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>

after that we will create the @SpringBootApplication class :

@SpringBootApplication
public class ExampleApplication {
    private static final Logger logger = LoggerFactory.getLogger(ExampleApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(ExampleApplication.class, args);
    }
}

then we have to create the model objects :

@Entity
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "NAME", length = 64)
    private String name;

    @OneToMany(cascade = CascadeType.ALL
            , mappedBy = "customer", fetch = FetchType.EAGER, orphanRemoval = true
    )
    private List<Order> orders;

    @Version
    private Long version;
.......
@Entity
@Table(name = "ORDERS")
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne
    @JoinColumn(name="CUSTOMER_ID")
    private Customer customer;

    @Column(name = "ORDER_NAME", length = 128)
    private String orderName;

    @Version
    private Long version;

due to the fact that order is a reserved word in sql, is better to change the tabe name to "ORDERS".

Also we are using @OneToMany(cascade = CascadeType.ALL , mappedBy = "customer", fetch = FetchType.EAGER, orphanRemoval = true), take care when using FetchType.EAGER, it is possible to load entire database in memmory, if you are not taking care of using it, be default JPA is using LAZY, but on this example to keep things simple i used EAGER.

Each entity had a field with  @Version , just to see what happens with this when we are changing a order.

On ExampleApplication we will define a CommandLineRunner bean :

 @Bean
    public CommandLineRunner exampleRunner(CustomerRepository customerRepository) {
        return (args) -> {
            Customer customer = new Customer("Customer 1", new ArrayList<>());
            customer.getOrders().add(new Order(customer, "order 1"));
            customer.getOrders().add(new Order(customer, "order 2"));
            customerRepository.save(customer);

            customerRepository.findAll().forEach(c -> {
                logger.info(c.toString());
            });
// The output 1 : 
//Customer{id=1, name='Customer 1', version=0, orders=[Order{id=1, orderName='order 1', version=0}, Order{id=2, orderName='order 2', version=0}]
            final Iterable<Customer> customers = customerRepository.findAll();
            customers.forEach(c -> {
                c.getOrders().forEach(order -> {
                    order.setOrderName(order.getOrderName() + "1");
                });
                customerRepository.save(c);
            });

            customerRepository.findAll().forEach(c -> {
                logger.info(c.toString());
            });
// The output 2 :
//Customer{id=1, name='Customer 1', version=0, orders=[Order{id=1, orderName='order 11', version=1}, Order{id=2, orderName='order 21', version=1}]}
            customer = customerRepository.findOne(customer.getId());
            customer.setName(customer.getName() + "1");
            customerRepository.save(customer);
            customerRepository.findAll().forEach(c -> {
                logger.info(c.toString());
            });
// The output 3 :
//Customer{id=1, name='Customer 11', version=1, orders=[Order{id=1, orderName='order 11', version=1}, Order{id=2, orderName='order 21', version=1}]}
        };
    }

As you can see on first output the version is 0 for all enitites, after changin the order name the version is changed only on those entities and on final optul after we changed the cutomer its version is updated to 1

 

 Download sources from git : sources

Category: Java Tutorials