diff --git a/persistence-modules/hibernate-libraries/create-database.sh b/persistence-modules/hibernate-libraries/create-database.sh
new file mode 100755
index 0000000000..da55dc917d
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/create-database.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+docker run \
+ -p 53306:3306 \
+ --name=mysql57-hibernate-types \
+ -e MYSQL_ALLOW_EMPTY_PASSWORD=true \
+ -v "${PWD}/docker/docker-entrypoint-initdb.d":/docker-entrypoint-initdb.d \
+ -d mysql:5.7
diff --git a/persistence-modules/hibernate-libraries/docker-compose.yml b/persistence-modules/hibernate-libraries/docker-compose.yml
new file mode 100644
index 0000000000..3ea9fef2e7
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/docker-compose.yml
@@ -0,0 +1,19 @@
+version: '3.2'
+
+services:
+ mysql:
+ image: mysql:5.7
+ container_name: mysql57
+ restart: unless-stopped
+ ports:
+ - 53306:3306
+ environment:
+ - MYSQL_ALLOW_EMPTY_PASSWORD=true
+ volumes :
+ - ./docker/etc/mysql/conf.d:/etc/mysql/conf.d
+ - ./docker/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "50m"
+ max-file: "1"
diff --git a/persistence-modules/hibernate-libraries/docker/docker-entrypoint-initdb.d/init-db.sql b/persistence-modules/hibernate-libraries/docker/docker-entrypoint-initdb.d/init-db.sql
new file mode 100644
index 0000000000..1df234f5a1
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/docker/docker-entrypoint-initdb.d/init-db.sql
@@ -0,0 +1,3 @@
+CREATE DATABASE hibernate_types;
+use hibernate_types;
+GRANT ALL PRIVILEGES ON hibernate_types.* TO 'mysql'@'%' IDENTIFIED BY 'admin';
diff --git a/persistence-modules/hibernate-libraries/pom.xml b/persistence-modules/hibernate-libraries/pom.xml
new file mode 100644
index 0000000000..ea2dda7e88
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/pom.xml
@@ -0,0 +1,188 @@
+
+
+ 4.0.0
+ hibernate-libraries
+ 0.0.1-SNAPSHOT
+ hibernate-libraries
+ Introduction into hibernate types library
+
+
+ com.baeldung
+ persistence-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ com.vladmihalcea
+ hibernate-types-52
+ ${hibernate-types.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+ ${spring-boot.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ ${spring-boot.version}
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ ${spring-boot.version}
+ runtime
+ true
+
+
+ org.hibernate
+ hibernate-core
+ ${hibernate.version}
+ provided
+
+
+ org.hibernate
+ hibernate-ehcache
+ ${hibernate.version}
+ test
+
+
+ org.hibernate
+ hibernate-testing
+ ${hibernate.version}
+ test
+
+
+ org.assertj
+ assertj-core
+ ${assertj-core.version}
+ test
+
+
+ mysql
+ mysql-connector-java
+ ${mysql.version}
+ runtime
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+ provided
+ true
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+ provided
+ true
+
+
+ javax.xml.bind
+ jaxb-api
+ ${jaxb.version}
+
+
+ org.javassist
+ javassist
+ ${javassist.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+ provided
+ true
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+ provided
+ true
+
+
+ net.ttddyy
+ datasource-proxy
+ ${datasource-proxy.version}
+ test
+
+
+ com.integralblue
+ log4jdbc-spring-boot-starter
+ ${log4jdbc.version}
+
+
+
+
+ hibernate-types
+
+
+ src/main/resources
+ true
+
+
+
+
+
+
+ integration
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ integration-test
+
+ test
+
+
+
+ none
+
+
+ **/*IntegrationTest.java
+
+
+
+
+
+
+
+
+
+
+
+ 3.15.0
+ 1.6
+ 29.0-jre
+ 2.9.7
+ 5.4.14.Final
+ 2.10.3
+ 1.8
+ 3.27.0-GA
+ 2.3.1
+ 2.0.0
+ 1.2.3
+ 3.0.2
+ 2.22.2
+ 3.8.1
+ 3.8.1
+ 8.0.19
+ 1.7.30
+ 2.1.3.RELEASE
+
+
+
diff --git a/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/Album.java b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/Album.java
new file mode 100644
index 0000000000..f18818c3a9
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/Album.java
@@ -0,0 +1,34 @@
+package com.baeldung.hibernate.types;
+
+import org.hibernate.annotations.Type;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Entity(name = "Album")
+@Table(name = "album")
+public class Album extends BaseEntity {
+ @Type(type = "json")
+ @Column(columnDefinition = "json")
+ private CoverArt coverArt;
+
+ @OneToMany(fetch = FetchType.EAGER)
+ private List songs;
+
+ public CoverArt getCoverArt() {
+ return coverArt;
+ }
+
+ public void setCoverArt(CoverArt coverArt) {
+ this.coverArt = coverArt;
+ }
+
+
+ public List getSongs() {
+ return songs;
+ }
+
+ public void setSong(List songs) {
+ this.songs = songs;
+ }
+}
diff --git a/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/AlbumRepository.java b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/AlbumRepository.java
new file mode 100644
index 0000000000..d89542de46
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/AlbumRepository.java
@@ -0,0 +1,8 @@
+package com.baeldung.hibernate.types;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface AlbumRepository extends CrudRepository {
+}
diff --git a/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/Artist.java b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/Artist.java
new file mode 100644
index 0000000000..8f3ccb44c5
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/Artist.java
@@ -0,0 +1,72 @@
+package com.baeldung.hibernate.types;
+
+import java.io.Serializable;
+
+public class Artist implements Serializable {
+
+ private String name;
+ private String country;
+ private String genre;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ public String getGenre() {
+ return genre;
+ }
+
+ public void setGenre(String genre) {
+ this.genre = genre;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((country == null) ? 0 : country.hashCode());
+ result = prime * result + ((genre == null) ? 0 : genre.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Artist other = (Artist) obj;
+ if (country == null) {
+ if (other.country != null)
+ return false;
+ } else if (!country.equals(other.country))
+ return false;
+ if (genre == null) {
+ if (other.genre != null)
+ return false;
+ } else if (!genre.equals(other.genre))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ return true;
+ }
+
+ }
diff --git a/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/BaseEntity.java b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/BaseEntity.java
new file mode 100644
index 0000000000..3e0fbc7595
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/BaseEntity.java
@@ -0,0 +1,37 @@
+package com.baeldung.hibernate.types;
+
+import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
+import com.vladmihalcea.hibernate.type.json.JsonStringType;
+import org.hibernate.annotations.TypeDef;
+import org.hibernate.annotations.TypeDefs;
+
+import javax.persistence.*;
+
+@TypeDefs({
+ @TypeDef(name = "json", typeClass = JsonStringType.class),
+ @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
+})
+@MappedSuperclass
+public class BaseEntity {
+ @Id
+ @GeneratedValue(strategy=GenerationType.AUTO)
+ @Column(name = "id", unique = true, nullable = false)
+ long id;
+ String 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;
+ }
+}
diff --git a/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/CoverArt.java b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/CoverArt.java
new file mode 100644
index 0000000000..bd71edc53c
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/CoverArt.java
@@ -0,0 +1,71 @@
+package com.baeldung.hibernate.types;
+
+import java.io.Serializable;
+
+public class CoverArt implements Serializable {
+
+ private String frontCoverArtUrl;
+ private String backCoverArtUrl;
+ private String upcCode;
+
+ public String getFrontCoverArtUrl() {
+ return frontCoverArtUrl;
+ }
+
+ public void setFrontCoverArtUrl(String frontCoverArtUrl) {
+ this.frontCoverArtUrl = frontCoverArtUrl;
+ }
+
+ public String getBackCoverArtUrl() {
+ return backCoverArtUrl;
+ }
+
+ public void setBackCoverArtUrl(String backCoverArtUrl) {
+ this.backCoverArtUrl = backCoverArtUrl;
+ }
+
+ public String getUpcCode() {
+ return upcCode;
+ }
+
+ public void setUpcCode(String upcCode) {
+ this.upcCode = upcCode;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((backCoverArtUrl == null) ? 0 : backCoverArtUrl.hashCode());
+ result = prime * result + ((frontCoverArtUrl == null) ? 0 : frontCoverArtUrl.hashCode());
+ result = prime * result + ((upcCode == null) ? 0 : upcCode.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ CoverArt other = (CoverArt) obj;
+ if (backCoverArtUrl == null) {
+ if (other.backCoverArtUrl != null)
+ return false;
+ } else if (!backCoverArtUrl.equals(other.backCoverArtUrl))
+ return false;
+ if (frontCoverArtUrl == null) {
+ if (other.frontCoverArtUrl != null)
+ return false;
+ } else if (!frontCoverArtUrl.equals(other.frontCoverArtUrl))
+ return false;
+ if (upcCode == null) {
+ if (other.upcCode != null)
+ return false;
+ } else if (!upcCode.equals(other.upcCode))
+ return false;
+ return true;
+ }
+}
diff --git a/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/HibernateTypesApplication.java b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/HibernateTypesApplication.java
new file mode 100644
index 0000000000..ac379f9ee2
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/HibernateTypesApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung.hibernate.types;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class HibernateTypesApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(HibernateTypesApplication.class, args);
+ }
+
+}
diff --git a/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/Song.java b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/Song.java
new file mode 100644
index 0000000000..2d22296024
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/Song.java
@@ -0,0 +1,57 @@
+package com.baeldung.hibernate.types;
+
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.TypeDef;
+
+import java.time.YearMonth;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import com.vladmihalcea.hibernate.type.basic.YearMonthIntegerType;
+
+@Entity(name = "Song")
+@Table(name = "song")
+@TypeDef(
+ typeClass = YearMonthIntegerType.class,
+ defaultForType = YearMonth.class
+)
+public class Song extends BaseEntity {
+
+ private Long length = 0L;
+
+ @Type(type = "json")
+ @Column(columnDefinition = "json")
+ private Artist artist;
+
+ @Column(
+ name = "recorded_on",
+ columnDefinition = "mediumint"
+ )
+ private YearMonth recordedOn = YearMonth.now();
+
+ public Long getLength() {
+ return length;
+ }
+
+ public void setLength(Long length) {
+ this.length = length;
+ }
+
+ public Artist getArtist() {
+ return artist;
+ }
+
+ public void setArtist(Artist artist) {
+ this.artist = artist;
+ }
+
+ public YearMonth getRecordedOn() {
+ return recordedOn;
+ }
+
+ public void setRecordedOn(YearMonth recordedOn) {
+ this.recordedOn = recordedOn;
+ }
+}
\ No newline at end of file
diff --git a/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/SongRepository.java b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/SongRepository.java
new file mode 100644
index 0000000000..e79e88108b
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/src/main/java/com/baeldung/hibernate/types/SongRepository.java
@@ -0,0 +1,8 @@
+package com.baeldung.hibernate.types;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface SongRepository extends CrudRepository {
+}
diff --git a/persistence-modules/hibernate-libraries/src/main/resources/application.properties b/persistence-modules/hibernate-libraries/src/main/resources/application.properties
new file mode 100644
index 0000000000..9588139eb0
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/src/main/resources/application.properties
@@ -0,0 +1,14 @@
+log4jdbc.dump.sql.addsemicolon=true
+log4jdbc.dump.sql.maxlinelength=0
+log4jdbc.trim.sql.extrablanklines=false
+logging.level.jdbc.audit=fatal
+logging.level.jdbc.connection=fatal
+logging.level.jdbc.resultset=fatal
+logging.level.jdbc.resultsettable=info
+logging.level.jdbc.sqlonly=fatal
+logging.level.jdbc.sqltiming=info
+spring.datasource.url=jdbc:mysql://localhost:53306/hibernate_types?serverTimezone=UTC&useSSL=false
+spring.datasource.username=root
+spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
+spring.jpa.hibernate.ddl-auto=create
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
diff --git a/persistence-modules/hibernate-libraries/src/main/resources/hibernate-types.properties b/persistence-modules/hibernate-libraries/src/main/resources/hibernate-types.properties
new file mode 100644
index 0000000000..226b50fafd
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/src/main/resources/hibernate-types.properties
@@ -0,0 +1 @@
+hibernate.types.print.banner=false
diff --git a/persistence-modules/hibernate-libraries/src/test/java/com/baeldung/hibernate/types/HibernateTypesIntegrationTest.java b/persistence-modules/hibernate-libraries/src/test/java/com/baeldung/hibernate/types/HibernateTypesIntegrationTest.java
new file mode 100644
index 0000000000..9d7479e77d
--- /dev/null
+++ b/persistence-modules/hibernate-libraries/src/test/java/com/baeldung/hibernate/types/HibernateTypesIntegrationTest.java
@@ -0,0 +1,181 @@
+package com.baeldung.hibernate.types;
+
+import com.google.common.collect.Lists;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.time.Duration;
+import java.time.YearMonth;
+import java.util.UUID;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SpringBootTest
+public class HibernateTypesIntegrationTest {
+
+ @Autowired
+ AlbumRepository albumRepository;
+
+ @Autowired
+ SongRepository songRepository;
+
+ private void deleteAll() {
+ albumRepository.deleteAll();
+ songRepository.deleteAll();
+ }
+
+ @BeforeEach
+ public void setUp() {
+ deleteAll();
+ }
+
+ @BeforeEach
+ public void tearDown() {
+ setUp();
+ }
+
+ @Test
+ void whenSavingHibernateTypes_thenTheCorrectJsonIsStoredInTheDatabase() {
+ Album emptyAlbum = new Album();
+ emptyAlbum = albumRepository.save(emptyAlbum);
+
+ Song emptySong = new Song();
+ emptySong = songRepository.save(emptySong);
+
+ Artist superstarArtist = new Artist();
+ superstarArtist.setCountry("England");
+ superstarArtist.setGenre("Pop");
+ superstarArtist.setName("Superstar");
+
+ Song aHappySong = new Song();
+ aHappySong.setArtist(superstarArtist);
+ aHappySong.setName("A Happy Song");
+ aHappySong.setLength(Duration.ofMinutes(4).getSeconds());
+ aHappySong = songRepository.save(aHappySong);
+
+ Song aSadSong = new Song();
+ aSadSong.setArtist(superstarArtist);
+ aSadSong.setName("A Sad Song");
+ aSadSong.setLength(Duration.ofMinutes(2).getSeconds());
+ aSadSong = songRepository.save(aSadSong);
+
+ Song anotherHappySong = new Song();
+ anotherHappySong.setArtist(superstarArtist);
+ anotherHappySong.setName("Another Happy Song");
+ anotherHappySong.setLength(Duration.ofMinutes(3).getSeconds());
+ anotherHappySong = songRepository.save(anotherHappySong);
+
+ Artist newcomer = new Artist();
+ newcomer.setCountry("Jamaica");
+ newcomer.setGenre("Reggae");
+ newcomer.setName("Newcomer");
+
+ Song aNewSong = new Song();
+ aNewSong.setArtist(newcomer);
+ aNewSong.setName("A New Song");
+ aNewSong.setLength(Duration.ofMinutes(5).getSeconds());
+ aNewSong = songRepository.save(aNewSong);
+
+ CoverArt superstarAlbumCoverArt = new CoverArt();
+ superstarAlbumCoverArt.setUpcCode(UUID.randomUUID().toString());
+ superstarAlbumCoverArt.setFrontCoverArtUrl("http://fakeurl-0");
+ superstarAlbumCoverArt.setBackCoverArtUrl("http://fakeurl-1");
+
+ Album superstarAlbum = new Album();
+ superstarAlbum.setCoverArt(superstarAlbumCoverArt);
+ superstarAlbum.setName("The Superstar Album");
+ superstarAlbum.setSong(Lists.newArrayList(aHappySong, aSadSong, anotherHappySong));
+ superstarAlbum = albumRepository.save(superstarAlbum);
+
+ CoverArt newcomerAlbumCoverArt = new CoverArt();
+ newcomerAlbumCoverArt.setUpcCode(UUID.randomUUID().toString());
+ newcomerAlbumCoverArt.setFrontCoverArtUrl("http://fakeurl-2");
+ newcomerAlbumCoverArt.setBackCoverArtUrl("http://fakeurl-3");
+
+ Album newcomerAlbum = new Album();
+ newcomerAlbum.setCoverArt(newcomerAlbumCoverArt);
+ newcomerAlbum.setName("The Newcomer Album");
+ newcomerAlbum.setSong(Lists.newArrayList(aNewSong));
+ albumRepository.save(newcomerAlbum);
+
+ Iterable selectAlbumsQueryResult = albumRepository.findAll();
+ assertThat(selectAlbumsQueryResult).hasSize(3);
+
+ Iterable selectSongsQueryResult = songRepository.findAll();
+ assertThat(selectSongsQueryResult).hasSize(5);
+
+ Album selectAlbumQueryResult;
+
+ selectAlbumQueryResult = albumRepository.findById(emptyAlbum.getId()).get();
+ assertThat(selectAlbumQueryResult.getName()).isNull();
+ assertThat(selectAlbumQueryResult.getCoverArt()).isNull();
+ assertThat(selectAlbumQueryResult.getSongs()).isNullOrEmpty();
+
+ selectAlbumQueryResult = albumRepository.findById(superstarAlbum.getId()).get();
+ assertThat(selectAlbumQueryResult.getName()).isEqualTo("The Superstar Album");
+ assertThat(selectAlbumQueryResult.getCoverArt().getFrontCoverArtUrl()).isEqualTo("http://fakeurl-0");
+ assertThat(selectAlbumQueryResult.getCoverArt().getBackCoverArtUrl()).isEqualTo("http://fakeurl-1");
+ assertThat(selectAlbumQueryResult.getSongs()).hasSize(3);
+ assertThat(selectAlbumQueryResult.getSongs()).usingFieldByFieldElementComparator().containsExactlyInAnyOrder(aHappySong, aSadSong, anotherHappySong);
+
+ selectAlbumQueryResult = albumRepository.findById(newcomerAlbum.getId()).get();
+ assertThat(selectAlbumQueryResult.getName()).isEqualTo("The Newcomer Album");
+ assertThat(selectAlbumQueryResult.getCoverArt().getFrontCoverArtUrl()).isEqualTo("http://fakeurl-2");
+ assertThat(selectAlbumQueryResult.getCoverArt().getBackCoverArtUrl()).isEqualTo("http://fakeurl-3");
+ assertThat(selectAlbumQueryResult.getSongs()).hasSize(1);
+ assertThat(selectAlbumQueryResult.getSongs()).usingFieldByFieldElementComparator().containsExactlyInAnyOrder(aNewSong);
+
+ Song selectSongQueryResult;
+
+ selectSongQueryResult = songRepository.findById(emptySong.getId()).get();
+ assertThat(selectSongQueryResult.getName()).isNull();
+ assertThat(selectSongQueryResult.getLength()).isZero();
+ assertThat(selectSongQueryResult.getArtist()).isNull();
+
+ selectSongQueryResult = songRepository.findById(aHappySong.getId()).get();
+ assertThat(selectSongQueryResult.getName()).isEqualTo("A Happy Song");
+ assertThat(selectSongQueryResult.getLength()).isEqualTo(Duration.ofMinutes(4).getSeconds());
+ assertThat(selectSongQueryResult.getArtist().getName()).isEqualTo("Superstar");
+ assertThat(selectSongQueryResult.getArtist().getGenre()).isEqualTo("Pop");
+ assertThat(selectSongQueryResult.getArtist().getCountry()).isEqualTo("England");
+
+ selectSongQueryResult = songRepository.findById(aSadSong.getId()).get();
+ assertThat(selectSongQueryResult.getName()).isEqualTo("A Sad Song");
+ assertThat(selectSongQueryResult.getLength()).isEqualTo(Duration.ofMinutes(2).getSeconds());
+ assertThat(selectSongQueryResult.getArtist().getName()).isEqualTo("Superstar");
+ assertThat(selectSongQueryResult.getArtist().getGenre()).isEqualTo("Pop");
+ assertThat(selectSongQueryResult.getArtist().getCountry()).isEqualTo("England");
+
+ selectSongQueryResult = songRepository.findById(anotherHappySong.getId()).get();
+ assertThat(selectSongQueryResult.getName()).isEqualTo("Another Happy Song");
+ assertThat(selectSongQueryResult.getLength()).isEqualTo(Duration.ofMinutes(3).getSeconds());
+ assertThat(selectSongQueryResult.getArtist().getName()).isEqualTo("Superstar");
+ assertThat(selectSongQueryResult.getArtist().getGenre()).isEqualTo("Pop");
+ assertThat(selectSongQueryResult.getArtist().getCountry()).isEqualTo("England");
+
+ selectSongQueryResult = songRepository.findById(aNewSong.getId()).get();
+ assertThat(selectSongQueryResult.getName()).isEqualTo("A New Song");
+ assertThat(selectSongQueryResult.getLength()).isEqualTo(Duration.ofMinutes(5).getSeconds());
+ assertThat(selectSongQueryResult.getArtist().getName()).isEqualTo("Newcomer");
+ assertThat(selectSongQueryResult.getArtist().getGenre()).isEqualTo("Reggae");
+ assertThat(selectSongQueryResult.getArtist().getCountry()).isEqualTo("Jamaica");
+ }
+
+ @Test
+ void whenSavingAHibernateTypeYearMonth_thenTheCorrectValueIsStoredInTheDatabase() {
+ Song mySong = new Song();
+ YearMonth now = YearMonth.of(2019, 12);
+ mySong.setArtist(new Artist());
+ mySong.setName("My Song");
+ mySong.setLength(Duration.ofMinutes(1).getSeconds());
+ mySong.setRecordedOn(now);
+ mySong = songRepository.save(mySong);
+
+ Song selectSongQueryResult;
+ selectSongQueryResult = songRepository.findById(mySong.getId()).get();
+ assertThat(selectSongQueryResult.getRecordedOn().getYear()).isEqualTo(2019);
+ assertThat(selectSongQueryResult.getRecordedOn().getMonthValue()).isEqualTo(12);
+ }
+}
diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml
index 78da896861..a03ba1ec5d 100644
--- a/persistence-modules/pom.xml
+++ b/persistence-modules/pom.xml
@@ -24,6 +24,7 @@
hibernate-mapping
hibernate-ogm
hibernate-annotations
+ hibernate-libraries
hibernate-jpa
hibernate-queries
hibernate-enterprise