Model

We will start implementing this layer of our applications with mapping entities from database to POJOs. Before that, let's create a new package inside model package and call it entities. Next, we will be doing validation, so let's add Hibernate Validator dependency to POM file:

<!-- Hibernate validator -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
</dependency>

Please note, that we didn't specifies version of Hibernate Validator, because Spring Boot managed it for us. Now, we can start with our entity classes based on JPA. For every table from database we will have one corresponding Java class. Inside entities package create a new file Manager.java:

package pms.model.entities;

import org.hibernate.validator.constraints.NotBlank;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "MANAGER")
public class Manager {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME", nullable = false)
    @NotBlank
    private String name;

    @OneToMany(mappedBy = "manager")
    private List<Project> projects;

    protected Manager() {
        projects = new ArrayList<>();
    }

    public Manager(String name) {
        this();
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Project> getProjects() {
        return projects;
    }

    public void setProjects(List<Project> projects) {
        this.projects = projects;
    }

    @Override
    public String toString() {
        return "Manager{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", no. of projects=" + projects.size() +
                '}';
    }
}

As we earlier said, object-relational metadata are specified by using annotations. We can see the following annotations:

  • @Entity - Declares the class as an entity (persistent POJO class).
  • @Table - Declares the table in relational database. If no table annotation is present, the JPA implementation will auto assign a table for the class. The JPA default table name is the name of the class (minus the package) with the first letter capitalized.
  • @Id - declares object id and should correspond to the primary key of the object's table.
  • @GeneratedValue - declares a generated by the sistem id (surogate id). It is possible to declare generation strategy because different databases have different ways of generating primary key values.
  • @Column - declares the column name in table in relational database. This annotation allows us to specify that other informations such as constraints.
  • @OneToMany - declares that we have one-to-many relationship in database. As we earlier see, we have this type of relationship between tables Manager and Project.

Besides this JPA annotations, in previous code listing we also can see one Hibernate Validator annotation:

  • @NotBlank - declares that string is not null and the trimmed length is greater than zero.

Except used annotations, the code in previous listing looks like any regular Java class. There are only one thing to remember: every entity class need an empty constructor which can be public or protected. An empty constructor is needed to create a new instance via reflection by persistence framework. If we don't have any additional constructors wth arguments for the class, than we don't need to provide an empty constructor because we get one per default.

In order to automatically use our validations (@NotBlank) it is necessary to configure following beans: LocalValidatorFactoryBean and MethodValidationPostProcessor in some of used configuration classes. In this tutorial we actually use Spring Boot feature of autoconfiguring it, so we can just add this two beans in our PmsApplication.java file:

package pms;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;

@SpringBootApplication
public class PmsApplication {

    @Bean
    public LocalValidatorFactoryBean validator() {
        final LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();

        return localValidatorFactoryBean;
    }

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        final MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
        methodValidationPostProcessor.setValidator(validator());

        return methodValidationPostProcessor;
    }

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

Next we can create the rest of our entity classes inside entities package.

Department.java:

package pms.model.entities;

import org.hibernate.validator.constraints.NotBlank;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "DEPARTMENT")
public class Department {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME", nullable = false, unique = true)
    @NotBlank
    private String name;

    @OneToMany(mappedBy = "department")
    private List<Employee> employees;

    protected Department() {
        employees = new ArrayList<>();
    }

    public Department(String name) {
        this();
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }

    @Override
    public String toString() {
        return "Department{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", no. of employees=" + employees.size() +
                '}';
    }
}

Employee.java

package pms.model.entities;

import org.hibernate.validator.constraints.NotBlank;

import javax.persistence.*;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME", nullable = false)
    @NotBlank
    private String name;

    @ManyToOne
    private Department department;

    protected Employee() {
    }

    public Employee(String name) {
        this();
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", department=" + department +
                '}';
    }
}

Here we have one new annotation:

  • @ManyToOne - as we earlier said between Department and Employee tables in database we have one-to-many relationship. In JPA we can declare in "one" entity" @OneToMany`` relationship and we can in "many" entity declare that we have@ManyToOne``` relationship. All relationships in Java and JPA are uniderectional, in that if a source object references a target object there is no guarantee that the target object also has a relationship to the source object. This is different than a relational database, in which relationships are defined through foreign keys and querying such that the inverse query always exists.

Project.java

package pms.model.entities;

import org.hibernate.validator.constraints.NotBlank;

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Entity
@Table(name = "PROJECT")
public class Project {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "TITLE", nullable = false, unique = true)
    @NotBlank
    private String title;

    @Column(name = "BUDGET")
    private BigDecimal budget;

    @Column(name = "PRIORITY")
    private String priority;

    @Column(name = "DEADLINE")
    private Date deadline;

    @ManyToOne
    private Manager manager;

    @ElementCollection
    @CollectionTable(name = "PROJECT_EMPLOYEE",
            joinColumns = @JoinColumn(name = "ID_PROJECT"))
    @MapKeyJoinColumn(name = "ID_EMPLOYEE")
    @Column(name = "HOURLY_RATE")
    private Map<Employee, BigDecimal> rates;

    protected Project() {
        rates = new HashMap<>();
    }

    public Project(String title, BigDecimal budget, Date deadline) {
        this();
        this.title = title;
        this.budget = budget;
        this.deadline = deadline;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public BigDecimal getBudget() {
        return budget;
    }

    public void setBudget(BigDecimal budget) {
        this.budget = budget;
    }

    public String getPriority() {
        return priority;
    }

    public void setPriority(String priority) {
        this.priority = priority;
    }

    public Date getDeadline() {
        return deadline;
    }

    public void setDeadline(Date deadline) {
        this.deadline = deadline;
    }

    public Manager getManager() {
        return manager;
    }

    public void setManager(Manager manager) {
        this.manager = manager;
    }

    public Map<Employee, BigDecimal> getRates() {
        return rates;
    }

    public void setRates(Map<Employee, BigDecimal> rates) {
        this.rates = rates;
    }

    public void setEmployeeHourlyRate(Employee employee, BigDecimal rate) {
        rates.put(employee, rate);
    }

    public void removeEmployee(Employee employee) {
        rates.remove(employee);
    }

    @Override
    public String toString() {
        return "Project{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", budget=" + budget +
                ", priority='" + priority + '\'' +
                ", deadline=" + deadline +
                ", manager=" + manager +
                ", no. of employees=" + rates.size() +
                '}';
    }
}

Here we have a couple of new annotations. In chapter 1 we saw that we have a many-to-many relationship between Project and Employee tables. In JPA relationships like this we can map using @ManyToMany annotation. But in this particular case in table Project_Employee we have one additional column hourly_rate and that case it is not cover by using @ManyToMany annotation. So here we use:

  • @ElementCollection - defined by JPA 2.0 standard. It is meant to handle several non-standard relationship mappings. Values annotated with this annotation are always stored in a separated table.
  • @CollectionTable - declare separate table where @ElementCollection values are stored.
  • @JoinColumn - declare a column for joining an entity association or element collection.
  • @MapKeyJoinColumn - specifies a mapping to an entity that is a map key. The map key join column is in the collection table, join table or table of the target entity that is used to represent the map.

If we now run application, we can see in console something similar to the following listing:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.2.5.RELEASE)

2015-08-18 14:08:06.416  INFO 10664 --- [lication.main()] pms.PmsApplication                       : Starting PmsApplication on bgl-milan-nikic with PID 10664 (C:\Development\personal\pms\target\classes started by Milan.Nikic in C:\Development\personal\pms)
2015-08-18 14:08:06.478  INFO 10664 --- [lication.main()] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6acce1af: startup date [Tue Aug 18 14:08:06 CEST 2015]; root of context hierarchy
2015-08-18 14:08:07.589  INFO 10664 --- [lication.main()] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'beanNameViewResolver': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2015-08-18 14:08:08.123  INFO 10664 --- [lication.main()] trationDelegate$BeanPostProcessorChecker : Bean 'pmsApplication' of type [class pms.PmsApplication{% math %}EnhancerBySpringCGLIB{% endmath %}41c93ed5] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-08-18 14:08:08.149  INFO 10664 --- [lication.main()] trationDelegate$BeanPostProcessorChecker : Bean 'validator' of type [class org.springframework.validation.beanvalidation.LocalValidatorFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-08-18 14:08:08.291  INFO 10664 --- [lication.main()] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [class org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration{% math %}EnhancerBySpringCGLIB{% endmath %}78bfadbe] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-08-18 14:08:08.313  INFO 10664 --- [lication.main()] trationDelegate$BeanPostProcessorChecker : Bean 'transactionAttributeSource' of type [class org.springframework.transaction.annotation.AnnotationTransactionAttributeSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-08-18 14:08:08.325  INFO 10664 --- [lication.main()] trationDelegate$BeanPostProcessorChecker : Bean 'transactionInterceptor' of type [class org.springframework.transaction.interceptor.TransactionInterceptor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-08-18 14:08:08.330  INFO 10664 --- [lication.main()] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.config.internalTransactionAdvisor' of type [class org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-08-18 14:08:08.984  INFO 10664 --- [lication.main()] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2015-08-18 14:08:09.231  INFO 10664 --- [lication.main()] o.apache.catalina.core.StandardService   : Starting service Tomcat
2015-08-18 14:08:09.233  INFO 10664 --- [lication.main()] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.0.23
2015-08-18 14:08:09.324  INFO 10664 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2015-08-18 14:08:09.325  INFO 10664 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2848 ms
2015-08-18 14:08:10.193  INFO 10664 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2015-08-18 14:08:10.198  INFO 10664 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'characterEncodingFilter' to: [/*]
2015-08-18 14:08:10.199  INFO 10664 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2015-08-18 14:08:10.848  INFO 10664 --- [lication.main()] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2015-08-18 14:08:10.864  INFO 10664 --- [lication.main()] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
    name: default
    ...]
2015-08-18 14:08:10.968  INFO 10664 --- [lication.main()] org.hibernate.Version                    : HHH000412: Hibernate Core {4.3.10.Final}
2015-08-18 14:08:10.970  INFO 10664 --- [lication.main()] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2015-08-18 14:08:10.972  INFO 10664 --- [lication.main()] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
2015-08-18 14:08:11.226  INFO 10664 --- [lication.main()] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
2015-08-18 14:08:11.329  INFO 10664 --- [lication.main()] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2015-08-18 14:08:11.509  INFO 10664 --- [lication.main()] o.h.h.i.ast.ASTQueryTranslatorFactory    : HHH000397: Using ASTQueryTranslatorFactory
2015-08-18 14:08:11.907  INFO 10664 --- [lication.main()] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000227: Running hbm2ddl schema export
2015-08-18 14:08:12.001  INFO 10664 --- [lication.main()] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000230: Schema export complete
2015-08-18 14:08:12.854  INFO 10664 --- [lication.main()] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6acce1af: startup date [Tue Aug 18 14:08:06 CEST 2015]; root of context hierarchy
2015-08-18 14:08:12.956  INFO 10664 --- [lication.main()] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2015-08-18 14:08:12.957  INFO 10664 --- [lication.main()] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
2015-08-18 14:08:12.994  INFO 10664 --- [lication.main()] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2015-08-18 14:08:12.994  INFO 10664 --- [lication.main()] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2015-08-18 14:08:13.047  INFO 10664 --- [lication.main()] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2015-08-18 14:08:13.284  INFO 10664 --- [lication.main()] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2015-08-18 14:08:13.364  INFO 10664 --- [lication.main()] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2015-08-18 14:08:13.366  INFO 10664 --- [lication.main()] pms.PmsApplication                       : Started PmsApplication in 7.432 seconds (JVM running for 16.576)

As we can see it should be without any errors and we can see that Spring Boot correctly recognize that we are using H2 database and that our schema was exported without errors. In order to see more details about database creation, let's log some messages from Hibernate. To do this, we need to create src/main/resources/logback.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <logger name="org.hibernate.SQL" level="DEBUG"/>
</configuration>

This logging configuration file is based on Spring Boot base.xml logback configuration so we don't have to think about loggers, formats, appending and so on. If we now start again application we can see more detailed log messages from Hibernate:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.2.5.RELEASE)

2015-08-18 14:23:05.161  INFO 11840 --- [lication.main()] pms.PmsApplication                       : Starting PmsApplication on bgl-milan-nikic with PID 11840 (C:\Development\personal\pms\target\classes started by Milan.Nikic in C:\Development\personal\pms)
2015-08-18 14:23:05.219  INFO 11840 --- [lication.main()] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@7e9870db: startup date [Tue Aug 18 14:23:05 CEST 2015]; root of context hierarchy
2015-08-18 14:23:06.759  INFO 11840 --- [lication.main()] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'beanNameViewResolver': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2015-08-18 14:23:07.593  INFO 11840 --- [lication.main()] trationDelegate$BeanPostProcessorChecker : Bean 'pmsApplication' of type [class pms.PmsApplication{% math %}EnhancerBySpringCGLIB{% endmath %}971ba98c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-08-18 14:23:07.619  INFO 11840 --- [lication.main()] trationDelegate$BeanPostProcessorChecker : Bean 'validator' of type [class org.springframework.validation.beanvalidation.LocalValidatorFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-08-18 14:23:07.765  INFO 11840 --- [lication.main()] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [class org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration{% math %}EnhancerBySpringCGLIB{% endmath %}ce121875] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-08-18 14:23:07.784  INFO 11840 --- [lication.main()] trationDelegate$BeanPostProcessorChecker : Bean 'transactionAttributeSource' of type [class org.springframework.transaction.annotation.AnnotationTransactionAttributeSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-08-18 14:23:07.793  INFO 11840 --- [lication.main()] trationDelegate$BeanPostProcessorChecker : Bean 'transactionInterceptor' of type [class org.springframework.transaction.interceptor.TransactionInterceptor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-08-18 14:23:07.801  INFO 11840 --- [lication.main()] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.config.internalTransactionAdvisor' of type [class org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2015-08-18 14:23:08.446  INFO 11840 --- [lication.main()] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2015-08-18 14:23:08.737  INFO 11840 --- [lication.main()] o.apache.catalina.core.StandardService   : Starting service Tomcat
2015-08-18 14:23:08.740  INFO 11840 --- [lication.main()] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.0.23
2015-08-18 14:23:08.844  INFO 11840 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2015-08-18 14:23:08.844  INFO 11840 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 3628 ms
2015-08-18 14:23:09.879  INFO 11840 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2015-08-18 14:23:09.883  INFO 11840 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'characterEncodingFilter' to: [/*]
2015-08-18 14:23:09.884  INFO 11840 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2015-08-18 14:23:10.464  INFO 11840 --- [lication.main()] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2015-08-18 14:23:10.479  INFO 11840 --- [lication.main()] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
    name: default
    ...]
2015-08-18 14:23:10.582  INFO 11840 --- [lication.main()] org.hibernate.Version                    : HHH000412: Hibernate Core {4.3.10.Final}
2015-08-18 14:23:10.585  INFO 11840 --- [lication.main()] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2015-08-18 14:23:10.587  INFO 11840 --- [lication.main()] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
2015-08-18 14:23:10.826  INFO 11840 --- [lication.main()] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
2015-08-18 14:23:10.924  INFO 11840 --- [lication.main()] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2015-08-18 14:23:11.115  INFO 11840 --- [lication.main()] o.h.h.i.ast.ASTQueryTranslatorFactory    : HHH000397: Using ASTQueryTranslatorFactory
2015-08-18 14:23:11.546  INFO 11840 --- [lication.main()] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000227: Running hbm2ddl schema export
2015-08-18 14:23:11.548 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : drop table department if exists
2015-08-18 14:23:11.548 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : drop table employee if exists
2015-08-18 14:23:11.548 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : drop table manager if exists
2015-08-18 14:23:11.548 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : drop table project if exists
2015-08-18 14:23:11.549 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : drop table project_employee if exists
2015-08-18 14:23:11.549 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : create table department (id bigint generated by default as identity, name varchar(255) not null, primary key (id))
2015-08-18 14:23:11.557 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : create table employee (id bigint generated by default as identity, name varchar(255) not null, department_ID bigint, primary key (id))
2015-08-18 14:23:11.559 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : create table manager (id bigint generated by default as identity, name varchar(255) not null, primary key (id))
2015-08-18 14:23:11.560 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : create table project (id bigint generated by default as identity, budget decimal(19,2), deadline timestamp, priority varchar(255), title varchar(255) not null, manager_ID bigint, primary key (id))
2015-08-18 14:23:11.561 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : create table project_employee (id_project bigint not null, hourly_rate decimal(19,2), id_employee bigint not null, primary key (id_project, id_employee))
2015-08-18 14:23:11.566 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : alter table department add constraint UK_1t68827l97cwyxo9r1u6t4p7d  unique (name)
2015-08-18 14:23:11.566 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : alter table project add constraint UK_etb9i6krbg45bl5o1kt0cc4q8  unique (title)
2015-08-18 14:23:11.567 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : alter table employee add constraint FK_h93wsue8agtyo9pradnhxatoe foreign key (department_ID) references department
2015-08-18 14:23:11.575 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : alter table project add constraint FK_3stfwh0ab0shm2n0g9wt3f8n2 foreign key (manager_ID) references manager
2015-08-18 14:23:11.576 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : alter table project_employee add constraint FK_3f02c8pup0ro3fdno7x818uk1 foreign key (id_employee) references employee
2015-08-18 14:23:11.579 DEBUG 11840 --- [lication.main()] org.hibernate.SQL                        : alter table project_employee add constraint FK_2prk8hb51v6x07nmtcveyl87d foreign key (id_project) references project
2015-08-18 14:23:11.581  INFO 11840 --- [lication.main()] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000230: Schema export complete
2015-08-18 14:23:12.435  INFO 11840 --- [lication.main()] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@7e9870db: startup date [Tue Aug 18 14:23:05 CEST 2015]; root of context hierarchy
2015-08-18 14:23:12.520  INFO 11840 --- [lication.main()] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2015-08-18 14:23:12.521  INFO 11840 --- [lication.main()] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
2015-08-18 14:23:12.553  INFO 11840 --- [lication.main()] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2015-08-18 14:23:12.553  INFO 11840 --- [lication.main()] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2015-08-18 14:23:12.607  INFO 11840 --- [lication.main()] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2015-08-18 14:23:12.816  INFO 11840 --- [lication.main()] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2015-08-18 14:23:12.902  INFO 11840 --- [lication.main()] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2015-08-18 14:23:12.904  INFO 11840 --- [lication.main()] pms.PmsApplication                       : Started PmsApplication in 7.991 seconds (JVM running for 14.571)

We can see that tables are correctly created so we can continue with implementing DAO layer.