DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Data Engineering
  3. Databases
  4. Spring Boot and Hibernate Tips

Spring Boot and Hibernate Tips

Running into problems when using Spring Boot and Hibernate together? Here are some common errors and how to handle them.

Mohit Sinha user avatar by
Mohit Sinha
·
Jan. 09, 19 · Tutorial
Like (19)
Save
Tweet
Share
38.68K Views

Join the DZone community and get the full member experience.

Join For Free

Hibernate needs no introduction. It is the most popular ORM out there for Java. Similarly, Spring Boot is the most powerful and easy-to-use framework.

This tutorial isn't about Hibernate or Spring Boot, there are tons of them out there. Instead, we'll look into some common errors that you may run into when using them together and how to fix them.

Dependencies

We'll use Gradle to build our project. I recommend using the Spring Initializr for bootstrapping your project.

We'll use:

  • Spring Boot 2
  • Spring Webflux
  • Spring Data JPA
  • Spring Data Envers
  • Jackson Annotations
  • Jackson DataType Hibernate
  • H2 Database
  • Lombok

Spring Data Envers allows us to access entity revisions managed by Hibernate Envers. Jackson Annotations will also help us to avoid the common Stack Overflow errors that are caused by JPA relationships.

Jackson DataType Hibernate Module will help with Hibernate types and lazy-loading aspects.

buildscript {
    ext {
        springBootVersion = '2.0.6.RELEASE'
    }
...
}

dependencies {
    implementation('org.springframework.boot:spring-boot-starter-data-jpa')
    implementation('org.springframework.boot:spring-boot-starter-webflux')
    implementation("org.springframework.data:spring-data-envers")
    implementation("com.fasterxml.jackson.core:jackson-annotations:2.9.7")
    implementation("com.fasterxml.jackson.datatype:jackson-datatype-hibernate5:2.9.7")
    runtimeOnly('com.h2database:h2')
    compileOnly('org.projectlombok:lombok')
...
}


We'll use H2 to run our project.

Entities

In this example, we'll use JPA to create universities and students. It's always a good idea to store common logic and properties in a superclass.

We will create a superclass for our entities and store common properties in it. Let's have a look at our BaseEntity class.

@Getter @Setter @NoArgsConstructor @AllArgsConstructor @FieldDefaults(level = AccessLevel.PRIVATE)
@MappedSuperclass
@EntityListeners({AuditingEntityListener.class})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public abstract class BaseEntity {
    @Id
    @GeneratedValue
    Long id;

    @CreatedDate
    LocalDateTime createdAt;
    @LastModifiedDate
    LocalDateTime updatedAt;
}


One thing you can notice is that I haven't used the @Data annotation from Lombok on our class.@Data annotation automatically adds @ToString annotation, which may cause Stack Overflow errors. Hence, it's better to manage the annotations manually.

@MappedSuperclass annotation allows entities to inherit properties from a base class. This annotation is very important if you want to inherit properties from a base class.

@EntityListeners({AuditingEntityListener.class}) enables auditing. We are using @CreatedDate and @LastModifiedDate to capture when the entity was created or modified. This will be taken care by Spring Data JPA.

@JsonIdentityInfo will avoid the Stack Overflow errors when converting our entities to JSON.
This annotation is required to break the infinite cycle due to the bi-directional relationships between our entities.

You may also want to check out @JsonBackReference and @JsonManagedReference to see if they fit better with your requirements.

Let's have a look at our University and Student entities.

@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder @FieldDefaults(level = AccessLevel.PRIVATE)
@Entity @Audited
public class Student extends BaseEntity{
    String name;
    @ManyToOne
    University university;
}


@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder @FieldDefaults(level = AccessLevel.PRIVATE)
@Entity @Audited
public class University extends BaseEntity{
    String name;
    String city;
    @OneToMany(mappedBy = "university")
    Set<Student> students = new HashSet<>();
}


@Audited will enable Hibernate managing the auditing (tracking changes) on that Entity.

Configuration

Let's check the configurations required to run our project.

Hibernate Jackson Module

@Bean
public Module hibernateModule(){
    return new Hibernate5Module();
}


We are registering a new Jackson Module.  Spring Boot will auto-detect it and register it to the ObjectMapper bean.

Hibernate Envers

To enable Envers auditing, we have to extend our Repositories with RevisionRepository.

Let's have a look at our UniversityRepository.

public interface UniversityRepository extends RevisionRepository<University, Long, Long>, JpaRepository<University,Long> {
}


We'll have to similarly do this for our StudentRepository.

public interface StudentRepository extends RevisionRepository<Student, Long, Long>, JpaRepository<Student,Long> {
}


We also have to annotate our main class with @EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class).

We'll look at the main class in a while after going through other annotations that we need.

Spring Data Auditing

To enable this, we'll have to annotate our main class with @EnableJpaAuditing.

Let's look at it.

@SpringBootApplication
@EnableJpaAuditing
@EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
public class HibernateTipsApplication {

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


Conclusion

I have tried explaining, with a simple example, how to create REST applications using Spring Boot and Hibernate.

This might solve some of your Stack Overflow errors. Otherwise, you might want to consider writing your own Data Transfer Objects (DTO).

If you need support for data types that aren't supported by the core Hibernate ORM, you might want to check out this library.

You can read more about it here:

  • Spring Data JPA

You can find the complete example on GitHub.

Spring Framework Spring Boot Hibernate Spring Data Database Stack overflow Annotation Data (computing) Jackson (API)

Published at DZone with permission of Mohit Sinha, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Educating the Next Generation of Cloud Engineers With Google Cloud
  • AIOps Being Powered by Robotic Data Automation
  • How To Convert HTML to PNG in Java
  • Mr. Over, the Engineer [Comic]

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: