Add plain hibernate sample

This commit is contained in:
Christoph Strobl
2022-10-25 11:50:33 +02:00
parent 5d940bbf60
commit d86dbe2e03
11 changed files with 314 additions and 0 deletions

1
hibernate/README.adoc Normal file
View File

@@ -0,0 +1 @@
Tests if Spring ORM - Hibernate works

20
hibernate/build.gradle Normal file
View File

@@ -0,0 +1,20 @@
plugins {
id 'java'
id 'org.springframework.boot'
id 'org.springframework.aot.smoke-test'
id 'org.graalvm.buildtools.native'
}
dependencies {
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
implementation("org.springframework.boot:spring-boot-starter-jdbc")
implementation("org.springframework:spring-orm")
implementation("jakarta.persistence:jakarta.persistence-api")
implementation("org.hibernate:hibernate-core:6.1.2.Final")
runtimeOnly("com.h2database:h2")
testImplementation("org.springframework.boot:spring-boot-starter-test")
aotSmokeTestImplementation(project(":aot-smoke-test-support"))
aotSmokeTestImplementation("org.awaitility:awaitility:4.2.0")
}

View File

@@ -0,0 +1,26 @@
package com.example.spring.orm;
import java.time.Duration;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.springframework.aot.smoketest.support.assertj.AssertableOutput;
import org.springframework.aot.smoketest.support.junit.AotSmokeTest;
import static org.assertj.core.api.Assertions.assertThat;
@AotSmokeTest
class HibernateApplicationAotTests {
@Test
void entityGraph(AssertableOutput output) {
Awaitility.await().atMost(Duration.ofSeconds(10)).untilAsserted(() -> {
assertThat(output)
.hasLineContaining("left join (book_authors a1_0 join author a1_1 on a1_1.id=a1_0.authors_id)")
.hasSingleLineContaining(
"namedEntityGraph: Book{title='Spring in Action', authors=[Author{name='Craig Walls'}]}");
});
}
}

View File

@@ -0,0 +1,61 @@
package com.example.spring.orm;
import java.util.Collections;
import java.util.List;
import com.example.spring.orm.model.Author;
import com.example.spring.orm.model.Book;
import jakarta.persistence.EntityGraph;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.hibernate.Session;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
@Transactional
public class CLR implements CommandLineRunner {
@PersistenceContext
private EntityManager entityManager;
@Override
public void run(String... args) {
var books = insertBooks();
entityGraph(books.iterator().next().getId());
}
public void entityGraph(Long id) {
EntityGraph entityGraph = entityManager.getEntityGraph("Book.authors");
System.out.println("entityGraph: " + entityGraph);
Book result = entityManager.find(Book.class, id,
Collections.singletonMap("jakarta.persistence.fetchgraph", entityGraph));
System.out.println("namedEntityGraph: " + result);
}
public List<Book> insertBooks() {
Book book = new Book(null, "Spring in Action");
Author author = new Author(null, "Craig Walls", Collections.emptySet());
book.getAuthors().add(author);
entityManager.persist(book);
System.out.println("book: " + book);
entityManager.flush();
entityManager.getEntityManagerFactory().getCache().evictAll();
Session session = entityManager.unwrap(Session.class);
if (session != null) {
session.clear(); // internal cache clear
}
return Collections.singletonList(book);
}
}

View File

@@ -0,0 +1,16 @@
package com.example.spring.orm;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication
@EnableTransactionManagement
public class HibernateApplication {
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(HibernateApplication.class, args);
Thread.currentThread().join(); // To be able to measure memory consumption
}
}

View File

@@ -0,0 +1,78 @@
package com.example.spring.orm.model;
import java.util.Objects;
import java.util.Set;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.PreRemove;
@Entity
public class Author {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(cascade = CascadeType.ALL)
private Set<Book> books;
protected Author() {
}
public Author(Long id, String name, Set<Book> books) {
this.id = id;
this.name = name;
this.books = books;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Book> getBooks() {
return books;
}
@PreRemove
public void preRemove() {
System.out.println("Pre remove author " + id);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Author author = (Author) o;
return Objects.equals(id, author.id) && Objects.equals(name, author.name)
&& Objects.equals(books, author.books);
}
@Override
public int hashCode() {
return Objects.hash(id, name, books);
}
@Override
public String toString() {
return "Author{" + "name='" + name + '\'' + '}';
}
}

View File

@@ -0,0 +1,79 @@
package com.example.spring.orm.model;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.NamedAttributeNode;
import jakarta.persistence.NamedEntityGraph;
import jakarta.persistence.OneToMany;
@Entity
@NamedEntityGraph(name = "Book.authors", attributeNodes = @NamedAttributeNode("authors"))
public class Book {
@Id
@GeneratedValue
private Long id;
private String title;
@OneToMany(cascade = CascadeType.ALL)
private Set<Author> authors = new HashSet<>();
protected Book() {
}
public Book(Long id, String title) {
this.id = id;
this.title = title;
}
public Long getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Set<Author> getAuthors() {
return authors;
}
public void setAuthors(Set<Author> authors) {
this.authors = authors;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Book book = (Book) o;
return Objects.equals(id, book.id) && Objects.equals(title, book.title);
}
@Override
public int hashCode() {
return Objects.hash(id, title);
}
@Override
public String toString() {
return "Book{" + "title='" + title + '\'' + ", authors=" + authors + '}';
}
}

View File

@@ -0,0 +1 @@
logging.level.org.hibernate.SQL=debug

View File

@@ -0,0 +1,17 @@
create table author
(
id bigint auto_increment primary key,
name varchar not null
);
create table book
(
id bigint auto_increment primary key,
author bigint not null references author (id),
title varchar not null
);
create table book_authors (
book_id bigint,
authors_id bigint
)

View File

@@ -0,0 +1,14 @@
package com.example.spring.orm;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class HibernateTests {
@Test
void contextLoads() {
}
}

View File

@@ -71,6 +71,7 @@ include "flyway"
include "freemarker-webflux"
include "freemarker-webmvc"
include "hateoas"
include "hibernate"
include "integration"
include "kotlin-functional"
include "jdbc-h2"