├── .gitignore ├── .vscode └── settings.json ├── 01-LogQueryExecutionTime ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── thorben │ │ │ └── janssen │ │ │ └── talk │ │ │ └── model │ │ │ └── Author.java │ └── resources │ │ └── META-INF │ │ └── persistence.xml │ └── test │ ├── java │ └── com │ │ └── thorben │ │ └── janssen │ │ └── talk │ │ └── TestLogging.java │ └── resources │ ├── data.sql │ ├── log4j.properties │ └── log4j2.xml ├── 02-JoinUnassociatedEntities ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── thorben │ │ │ └── janssen │ │ │ └── talk │ │ │ └── model │ │ │ ├── Book.java │ │ │ └── Review.java │ └── resources │ │ └── META-INF │ │ └── persistence.xml │ └── test │ ├── java │ └── com │ │ └── thorben │ │ └── janssen │ │ └── talk │ │ └── TestJoinUnassociatedEntities.java │ └── resources │ ├── data.sql │ ├── log4j.properties │ └── log4j2.xml ├── 03-DatabaseViews ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── thorben │ │ │ └── janssen │ │ │ └── talk │ │ │ └── model │ │ │ ├── Author.java │ │ │ ├── Book.java │ │ │ ├── BookView.java │ │ │ └── Publisher.java │ └── resources │ │ └── META-INF │ │ └── persistence.xml │ └── test │ ├── java │ └── com │ │ └── thorben │ │ └── janssen │ │ └── talk │ │ └── TestViewEntity.java │ └── resources │ ├── create-database.sql │ ├── data.sql │ ├── drop-database.sql │ ├── log4j.properties │ └── log4j2.xml ├── 04-OrderAssociation ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── thorben │ │ │ └── janssen │ │ │ └── talk │ │ │ └── model │ │ │ ├── Author.java │ │ │ ├── Book.java │ │ │ └── Publisher.java │ └── resources │ │ └── META-INF │ │ └── persistence.xml │ └── test │ ├── java │ └── com │ │ └── thorben │ │ └── janssen │ │ └── talk │ │ └── TestOrderRelationships.java │ └── resources │ ├── data.sql │ ├── log4j.properties │ └── log4j2.xml ├── 05-KeepAssociationOrder ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── thorben │ │ │ └── janssen │ │ │ └── talk │ │ │ └── model │ │ │ ├── Author.java │ │ │ └── Book.java │ └── resources │ │ └── META-INF │ │ └── persistence.xml │ └── test │ ├── java │ └── com │ │ └── thorben │ │ └── janssen │ │ └── talk │ │ └── TestOrderRelationships.java │ └── resources │ ├── log4j.properties │ └── log4j2.xml ├── 06-PrimaryKeyUuid ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── thorben │ │ │ └── janssen │ │ │ └── talk │ │ │ └── model │ │ │ └── Author.java │ └── resources │ │ └── META-INF │ │ └── persistence.xml │ └── test │ ├── java │ └── com │ │ └── thorben │ │ └── janssen │ │ └── talk │ │ └── TestUUIDPrimaryKey.java │ └── resources │ ├── log4j.properties │ └── log4j2.xml ├── 07-MapOptionalAssociations ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── thorben │ │ │ └── janssen │ │ │ └── talk │ │ │ └── model │ │ │ ├── Book.java │ │ │ └── Publisher.java │ └── resources │ │ └── META-INF │ │ └── persistence.xml │ └── test │ ├── java │ └── com │ │ └── thorben │ │ └── janssen │ │ └── talk │ │ └── TestMapOptionalAssociation.java │ └── resources │ ├── data.sql │ ├── log4j.properties │ └── log4j2.xml ├── 08-EmbeddableRecord ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── thorben │ │ │ └── janssen │ │ │ └── talk │ │ │ └── model │ │ │ ├── Address.java │ │ │ ├── AddressInstantiator.java │ │ │ ├── Author.java │ │ │ └── AuthorId.java │ └── resources │ │ └── META-INF │ │ └── persistence.xml │ └── test │ ├── java │ └── com │ │ └── thorben │ │ └── janssen │ │ └── talk │ │ └── TestPrimaryKeyRecord.java │ └── resources │ └── log4j2.xml ├── 09-SimplifiedJsonMapping ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── thorben │ │ │ └── janssen │ │ │ └── talk │ │ │ └── model │ │ │ ├── Address.java │ │ │ ├── AddressInstantiator.java │ │ │ └── Author.java │ └── resources │ │ └── META-INF │ │ └── persistence.xml │ └── test │ ├── java │ └── com │ │ └── thorben │ │ └── janssen │ │ └── talk │ │ └── TestJsonSupport.java │ └── resources │ └── log4j2.xml ├── 10-MultiTenancy ├── .gitignore ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── thorben │ │ └── janssen │ │ └── talk │ │ ├── model │ │ └── Book.java │ │ └── multitenancy │ │ ├── MultiTenantConnectionProvider.java │ │ └── TenantIdResolver.java │ └── test │ ├── java │ └── com │ │ └── thorben │ │ └── janssen │ │ └── talk │ │ └── model │ │ └── TestMultiTenancy.java │ └── resources │ ├── create-database.sql │ ├── data.sql │ ├── drop-database.sql │ ├── hibernate.properties │ └── log4j2.xml ├── 11-Auditing ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── thorben │ │ │ └── janssen │ │ │ └── talk │ │ │ └── model │ │ │ └── Book.java │ └── resources │ │ └── META-INF │ │ └── persistence.xml │ └── test │ ├── java │ └── com │ │ └── thorben │ │ └── janssen │ │ └── talk │ │ └── TestEnvers.java │ └── resources │ ├── log4j.properties │ └── log4j2.xml ├── docker ├── docker-compose.yml ├── pgadmin │ ├── Dockerfile │ └── servers.json └── postgres │ ├── Dockerfile │ └── create-db.sql └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | .project 21 | .classpath 22 | 23 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 24 | hs_err_pid* 25 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "java.configuration.updateBuildConfiguration": "automatic" 3 | } -------------------------------------------------------------------------------- /01-LogQueryExecutionTime/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | .settings/ 3 | .project 4 | .classpath -------------------------------------------------------------------------------- /01-LogQueryExecutionTime/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | jar 7 | 8 | 9 | org.hibernate.orm 10 | hibernate-core 11 | 12 | 13 | junit 14 | junit 15 | test 16 | 17 | 18 | org.postgresql 19 | postgresql 20 | test 21 | 22 | 23 | org.apache.logging.log4j 24 | log4j-api 25 | 26 | 27 | org.apache.logging.log4j 28 | log4j-core 29 | test 30 | 31 | 32 | 01-LogQueryExecutionTime 33 | 34 | com.thorben.janssen.talks 35 | HibernateTips 36 | 1.0.0-SNAPSHOT 37 | .. 38 | 39 | -------------------------------------------------------------------------------- /01-LogQueryExecutionTime/src/main/java/com/thorben/janssen/talk/model/Author.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import jakarta.persistence.Entity; 4 | import jakarta.persistence.GeneratedValue; 5 | import jakarta.persistence.GenerationType; 6 | import jakarta.persistence.Id; 7 | import jakarta.persistence.Version; 8 | 9 | @Entity 10 | public class Author { 11 | 12 | @Id 13 | @GeneratedValue(strategy = GenerationType.SEQUENCE) 14 | private Long id; 15 | 16 | @Version 17 | private int version; 18 | 19 | private String firstName; 20 | 21 | private String lastName; 22 | 23 | public Long getId() { 24 | return this.id; 25 | } 26 | 27 | public int getVersion() { 28 | return this.version; 29 | } 30 | 31 | public String getFirstName() { 32 | return firstName; 33 | } 34 | 35 | public void setFirstName(String firstName) { 36 | this.firstName = firstName; 37 | } 38 | 39 | public String getLastName() { 40 | return lastName; 41 | } 42 | 43 | public void setLastName(String lastName) { 44 | this.lastName = lastName; 45 | } 46 | 47 | @Override 48 | public boolean equals(Object obj) { 49 | if (this == obj) { 50 | return true; 51 | } 52 | if (!(obj instanceof Author)) { 53 | return false; 54 | } 55 | Author other = (Author) obj; 56 | if (id != null) { 57 | if (!id.equals(other.id)) { 58 | return false; 59 | } 60 | } 61 | return true; 62 | } 63 | 64 | @Override 65 | public int hashCode() { 66 | return 31; 67 | } 68 | 69 | @Override 70 | public String toString() { 71 | String result = getClass().getSimpleName() + " "; 72 | if (firstName != null && !firstName.trim().isEmpty()) 73 | result += "firstName: " + firstName; 74 | if (lastName != null && !lastName.trim().isEmpty()) 75 | result += ", lastName: " + lastName; 76 | return result; 77 | } 78 | } -------------------------------------------------------------------------------- /01-LogQueryExecutionTime/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Hibernate Tips 7 | org.hibernate.jpa.HibernatePersistenceProvider 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /01-LogQueryExecutionTime/src/test/java/com/thorben/janssen/talk/TestLogging.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | import com.thorben.janssen.talk.model.Author; 10 | 11 | import jakarta.persistence.EntityManager; 12 | import jakarta.persistence.EntityManagerFactory; 13 | import jakarta.persistence.Persistence; 14 | import jakarta.persistence.TypedQuery; 15 | 16 | public class TestLogging { 17 | 18 | Logger log = LogManager.getLogger(this.getClass().getName()); 19 | 20 | private EntityManagerFactory emf; 21 | 22 | @Before 23 | public void init() { 24 | emf = Persistence.createEntityManagerFactory("my-persistence-unit"); 25 | } 26 | 27 | @After 28 | public void close() { 29 | emf.close(); 30 | } 31 | 32 | @Test 33 | public void selectAuthors() { 34 | log.info("... selectAuthors ..."); 35 | 36 | EntityManager em = emf.createEntityManager(); 37 | em.getTransaction().begin(); 38 | 39 | TypedQuery q = em.createQuery("SELECT a FROM Author a WHERE a.id = :id", Author.class); 40 | q.setParameter("id", 1L); 41 | Author a = q.getSingleResult(); 42 | 43 | a.setFirstName("Changed"); 44 | 45 | em.getTransaction().commit(); 46 | em.close(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /01-LogQueryExecutionTime/src/test/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO author (id, firstname, lastname, version) VALUES (1, 'Joshua', 'Bloch', 0); 2 | INSERT INTO author (id, firstname, lastname, version) VALUES (2, 'Gavin', 'King', 0); 3 | INSERT INTO author (id, firstname, lastname, version) VALUES (3, 'Christian', 'Bauer', 0); 4 | INSERT INTO author (id, firstname, lastname, version) VALUES (4, 'Gary', 'Gregory', 0); 5 | INSERT INTO author (id, firstname, lastname, version) VALUES (5, 'Raoul-Gabriel', 'Urma', 0); 6 | INSERT INTO author (id, firstname, lastname, version) VALUES (6, 'Mario', 'Fusco', 0); 7 | INSERT INTO author (id, firstname, lastname, version) VALUES (7, 'Alan', 'Mycroft', 0); 8 | INSERT INTO author (id, firstname, lastname, version) VALUES (8, 'Andrew Lee', 'Rubinger', 0); 9 | INSERT INTO author (id, firstname, lastname, version) VALUES (9, 'Aslak', 'Knutsen', 0); 10 | INSERT INTO author (id, firstname, lastname, version) VALUES (10, 'Bill', 'Burke', 0); 11 | INSERT INTO author (id, firstname, lastname, version) VALUES (11, 'Scott', 'Oaks', 0); -------------------------------------------------------------------------------- /01-LogQueryExecutionTime/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 2 | log4j.appender.stdout.Target=System.out 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n 5 | 6 | log4j.rootLogger=info, stdout 7 | # basic log level for all messages 8 | log4j.logger.org.hibernate=info 9 | 10 | # SQL statements and parameters 11 | #log4j.logger.org.hibernate.SQL=debug 12 | #log4j.logger.org.hibernate.type.descriptor.sql=trace 13 | log4j.logger.org.hibernate.stat=debug -------------------------------------------------------------------------------- /01-LogQueryExecutionTime/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /02-JoinUnassociatedEntities/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /02-JoinUnassociatedEntities/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | jar 7 | 8 | 9 | org.hibernate.orm 10 | hibernate-core 11 | 12 | 13 | junit 14 | junit 15 | test 16 | 17 | 18 | org.postgresql 19 | postgresql 20 | test 21 | 22 | 23 | org.apache.logging.log4j 24 | log4j-api 25 | 26 | 27 | org.apache.logging.log4j 28 | log4j-core 29 | test 30 | 31 | 32 | 03-JoinUnassociatedEntities 33 | 34 | com.thorben.janssen.talks 35 | HibernateTips 36 | 1.0.0-SNAPSHOT 37 | .. 38 | 39 | 40 | -------------------------------------------------------------------------------- /02-JoinUnassociatedEntities/src/main/java/com/thorben/janssen/talk/model/Book.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.util.Date; 4 | 5 | import jakarta.persistence.Column; 6 | import jakarta.persistence.Entity; 7 | import jakarta.persistence.GeneratedValue; 8 | import jakarta.persistence.GenerationType; 9 | import jakarta.persistence.Id; 10 | import jakarta.persistence.Temporal; 11 | import jakarta.persistence.TemporalType; 12 | import jakarta.persistence.Version; 13 | 14 | @Entity 15 | public class Book { 16 | 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.AUTO) 19 | @Column(name = "id", updatable = false, nullable = false) 20 | private Long id; 21 | 22 | @Version 23 | private int version; 24 | 25 | private String title; 26 | 27 | @Temporal(TemporalType.DATE) 28 | private Date publishingDate; 29 | 30 | public Long getId() { 31 | return this.id; 32 | } 33 | 34 | public int getVersion() { 35 | return this.version; 36 | } 37 | 38 | public String getTitle() { 39 | return title; 40 | } 41 | 42 | public void setTitle(String title) { 43 | this.title = title; 44 | } 45 | 46 | public Date getPublishingDate() { 47 | return publishingDate; 48 | } 49 | 50 | public void setPublishingDate(Date publishingDate) { 51 | this.publishingDate = publishingDate; 52 | } 53 | 54 | @Override 55 | public boolean equals(Object obj) { 56 | if (this == obj) { 57 | return true; 58 | } 59 | if (!(obj instanceof Book)) { 60 | return false; 61 | } 62 | Book other = (Book) obj; 63 | if (id != null) { 64 | if (!id.equals(other.id)) { 65 | return false; 66 | } 67 | } 68 | return true; 69 | } 70 | 71 | @Override 72 | public int hashCode() { 73 | return 31; 74 | } 75 | 76 | @Override 77 | public String toString() { 78 | String result = getClass().getSimpleName() + " "; 79 | if (title != null && !title.trim().isEmpty()) 80 | result += "title: " + title; 81 | return result; 82 | } 83 | } -------------------------------------------------------------------------------- /02-JoinUnassociatedEntities/src/main/java/com/thorben/janssen/talk/model/Review.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import jakarta.persistence.Column; 4 | import jakarta.persistence.Entity; 5 | import jakarta.persistence.GeneratedValue; 6 | import jakarta.persistence.GenerationType; 7 | import jakarta.persistence.Id; 8 | 9 | @Entity 10 | public class Review { 11 | 12 | @Id 13 | @GeneratedValue(strategy = GenerationType.AUTO) 14 | @Column(name = "id", updatable = false, nullable = false) 15 | private Long id; 16 | 17 | private String comment; 18 | 19 | private Long fkBook; 20 | 21 | public Long getId() { 22 | return id; 23 | } 24 | 25 | public String getComment() { 26 | return comment; 27 | } 28 | 29 | public void setComment(String comment) { 30 | this.comment = comment; 31 | } 32 | 33 | public Long getFkBook() { 34 | return fkBook; 35 | } 36 | 37 | public void setFkBook(Long fkBook) { 38 | this.fkBook = fkBook; 39 | } 40 | 41 | @Override 42 | public int hashCode() { 43 | return 31; 44 | } 45 | 46 | @Override 47 | public boolean equals(Object obj) { 48 | if (this == obj) 49 | return true; 50 | if (obj == null) 51 | return false; 52 | if (getClass() != obj.getClass()) 53 | return false; 54 | Review other = (Review) obj; 55 | if (id == null) { 56 | if (other.id != null) 57 | return false; 58 | } else if (!id.equals(other.id)) 59 | return false; 60 | return true; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /02-JoinUnassociatedEntities/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Hibernate Tips 7 | org.hibernate.jpa.HibernatePersistenceProvider 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /02-JoinUnassociatedEntities/src/test/java/com/thorben/janssen/talk/TestJoinUnassociatedEntities.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | import jakarta.persistence.EntityManager; 10 | import jakarta.persistence.EntityManagerFactory; 11 | import jakarta.persistence.Persistence; 12 | import jakarta.persistence.Query; 13 | 14 | public class TestJoinUnassociatedEntities { 15 | 16 | Logger log = LogManager.getLogger(this.getClass().getName()); 17 | 18 | private EntityManagerFactory emf; 19 | 20 | @Before 21 | public void init() { 22 | emf = Persistence.createEntityManagerFactory("my-persistence-unit"); 23 | } 24 | 25 | @After 26 | public void close() { 27 | emf.close(); 28 | } 29 | 30 | @Test 31 | public void joinUnassociated() { 32 | log.info("... joinUnassociated ..."); 33 | 34 | EntityManager em = emf.createEntityManager(); 35 | em.getTransaction().begin(); 36 | 37 | Query q = em.createQuery("SELECT b.title, count(r.id) FROM Book b INNER JOIN Review r ON r.fkBook = b.id GROUP BY b.title").setFirstResult(0).setMaxResults(5); 38 | Object[] r = (Object[]) q.getSingleResult(); 39 | log.info(r[0] + " received " + r[1] + " reviews."); 40 | 41 | em.getTransaction().commit(); 42 | em.close(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /02-JoinUnassociatedEntities/src/test/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO book (id, publishingdate, title, version) VALUES (1, '2017-04-04', 'Hibernate Tips', 0); 2 | 3 | INSERT INTO review (id, comment, fkBook) VALUES (1, 'This is a review', 1); 4 | INSERT INTO review (id, comment, fkBook) VALUES (2, 'This is another review', 1); -------------------------------------------------------------------------------- /02-JoinUnassociatedEntities/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 2 | log4j.appender.stdout.Target=System.out 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n 5 | 6 | log4j.rootLogger=info, stdout 7 | # basic log level for all messages 8 | log4j.logger.org.hibernate=info 9 | 10 | # SQL statements and parameters 11 | log4j.logger.org.hibernate.SQL=debug 12 | #log4j.logger.org.hibernate.type.descriptor.sql=trace -------------------------------------------------------------------------------- /02-JoinUnassociatedEntities/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /03-DatabaseViews/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /03-DatabaseViews/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | jar 7 | 8 | 9 | org.hibernate.orm 10 | hibernate-core 11 | 12 | 13 | junit 14 | junit 15 | test 16 | 17 | 18 | org.postgresql 19 | postgresql 20 | test 21 | 22 | 23 | org.apache.logging.log4j 24 | log4j-api 25 | 26 | 27 | org.apache.logging.log4j 28 | log4j-core 29 | test 30 | 31 | 32 | 04-DatabaseViews 33 | 34 | com.thorben.janssen.talks 35 | HibernateTips 36 | 1.0.0-SNAPSHOT 37 | .. 38 | 39 | 40 | -------------------------------------------------------------------------------- /03-DatabaseViews/src/main/java/com/thorben/janssen/talk/model/Author.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import jakarta.persistence.Column; 7 | import jakarta.persistence.Entity; 8 | import jakarta.persistence.GeneratedValue; 9 | import jakarta.persistence.GenerationType; 10 | import jakarta.persistence.Id; 11 | import jakarta.persistence.ManyToMany; 12 | import jakarta.persistence.Version; 13 | 14 | @Entity 15 | public class Author { 16 | 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.AUTO) 19 | @Column(name = "id", updatable = false, nullable = false) 20 | private Long id; 21 | 22 | @Version 23 | private int version; 24 | 25 | private String firstName; 26 | 27 | private String lastName; 28 | 29 | @ManyToMany(mappedBy="authors") 30 | private List books = new ArrayList(); 31 | 32 | public Long getId() { 33 | return this.id; 34 | } 35 | 36 | public int getVersion() { 37 | return this.version; 38 | } 39 | 40 | public String getFirstName() { 41 | return firstName; 42 | } 43 | 44 | public void setFirstName(String firstName) { 45 | this.firstName = firstName; 46 | } 47 | 48 | public String getLastName() { 49 | return lastName; 50 | } 51 | 52 | public void setLastName(String lastName) { 53 | this.lastName = lastName; 54 | } 55 | 56 | public List getBooks() { 57 | return this.books; 58 | } 59 | 60 | public void setBooks(final List books) { 61 | this.books = books; 62 | } 63 | 64 | @Override 65 | public boolean equals(Object obj) { 66 | if (this == obj) { 67 | return true; 68 | } 69 | if (!(obj instanceof Author)) { 70 | return false; 71 | } 72 | Author other = (Author) obj; 73 | if (id != null) { 74 | if (!id.equals(other.id)) { 75 | return false; 76 | } 77 | } 78 | return true; 79 | } 80 | 81 | @Override 82 | public int hashCode() { 83 | return 31; 84 | } 85 | 86 | @Override 87 | public String toString() { 88 | String result = getClass().getSimpleName() + " "; 89 | if (firstName != null && !firstName.trim().isEmpty()) 90 | result += "firstName: " + firstName; 91 | if (lastName != null && !lastName.trim().isEmpty()) 92 | result += ", lastName: " + lastName; 93 | return result; 94 | } 95 | } -------------------------------------------------------------------------------- /03-DatabaseViews/src/main/java/com/thorben/janssen/talk/model/Book.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.util.Date; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | import jakarta.persistence.Column; 8 | import jakarta.persistence.Entity; 9 | import jakarta.persistence.GeneratedValue; 10 | import jakarta.persistence.GenerationType; 11 | import jakarta.persistence.Id; 12 | import jakarta.persistence.JoinColumn; 13 | import jakarta.persistence.JoinTable; 14 | import jakarta.persistence.ManyToMany; 15 | import jakarta.persistence.ManyToOne; 16 | import jakarta.persistence.Temporal; 17 | import jakarta.persistence.TemporalType; 18 | import jakarta.persistence.Version; 19 | 20 | @Entity 21 | public class Book { 22 | 23 | @Id 24 | @GeneratedValue(strategy = GenerationType.AUTO) 25 | @Column(name = "id", updatable = false, nullable = false) 26 | private Long id; 27 | 28 | @Version 29 | private int version; 30 | 31 | private String title; 32 | 33 | @Temporal(TemporalType.DATE) 34 | private Date publishingDate; 35 | 36 | @ManyToOne 37 | @JoinColumn(name="publisherid") 38 | private Publisher publisher; 39 | 40 | @ManyToMany 41 | @JoinTable( 42 | name="BookAuthor", 43 | joinColumns={@JoinColumn(name="bookId", referencedColumnName="id")}, 44 | inverseJoinColumns={@JoinColumn(name="authorId", referencedColumnName="id")}) 45 | private Set authors = new HashSet(); 46 | 47 | public Long getId() { 48 | return this.id; 49 | } 50 | 51 | public int getVersion() { 52 | return this.version; 53 | } 54 | 55 | public String getTitle() { 56 | return title; 57 | } 58 | 59 | public void setTitle(String title) { 60 | this.title = title; 61 | } 62 | 63 | public Date getPublishingDate() { 64 | return publishingDate; 65 | } 66 | 67 | public void setPublishingDate(Date publishingDate) { 68 | this.publishingDate = publishingDate; 69 | } 70 | 71 | public Publisher getPublisher() { 72 | return this.publisher; 73 | } 74 | 75 | public void setPublisher(final Publisher publisher) { 76 | this.publisher = publisher; 77 | } 78 | 79 | public Set getAuthors() { 80 | return authors; 81 | } 82 | 83 | public void setAuthors(Set authors) { 84 | this.authors = authors; 85 | } 86 | 87 | @Override 88 | public boolean equals(Object obj) { 89 | if (this == obj) { 90 | return true; 91 | } 92 | if (!(obj instanceof Book)) { 93 | return false; 94 | } 95 | Book other = (Book) obj; 96 | if (id != null) { 97 | if (!id.equals(other.id)) { 98 | return false; 99 | } 100 | } 101 | return true; 102 | } 103 | 104 | @Override 105 | public int hashCode() { 106 | return 31; 107 | } 108 | 109 | @Override 110 | public String toString() { 111 | String result = getClass().getSimpleName() + " "; 112 | if (title != null && !title.trim().isEmpty()) 113 | result += "title: " + title; 114 | return result; 115 | } 116 | } -------------------------------------------------------------------------------- /03-DatabaseViews/src/main/java/com/thorben/janssen/talk/model/BookView.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.time.LocalDate; 4 | 5 | import org.hibernate.annotations.Immutable; 6 | 7 | import jakarta.persistence.Entity; 8 | import jakarta.persistence.Id; 9 | 10 | @Entity 11 | @Immutable 12 | public class BookView { 13 | 14 | @Id 15 | private Long id; 16 | 17 | private int version; 18 | 19 | private String title; 20 | 21 | private LocalDate publishingDate; 22 | 23 | private String authors; 24 | 25 | public Long getId() { 26 | return this.id; 27 | } 28 | 29 | public void setId(final Long id) { 30 | this.id = id; 31 | } 32 | 33 | public int getVersion() { 34 | return this.version; 35 | } 36 | 37 | public void setVersion(final int version) { 38 | this.version = version; 39 | } 40 | 41 | @Override 42 | public boolean equals(Object obj) { 43 | if (this == obj) { 44 | return true; 45 | } 46 | if (!(obj instanceof BookView)) { 47 | return false; 48 | } 49 | BookView other = (BookView) obj; 50 | if (id != null) { 51 | if (!id.equals(other.id)) { 52 | return false; 53 | } 54 | } 55 | return true; 56 | } 57 | 58 | @Override 59 | public int hashCode() { 60 | final int prime = 31; 61 | int result = 1; 62 | result = prime * result + ((id == null) ? 0 : id.hashCode()); 63 | return result; 64 | } 65 | 66 | public String getTitle() { 67 | return title; 68 | } 69 | 70 | // public void setTitle(String title) { 71 | // this.title = title; 72 | // } 73 | 74 | public LocalDate getPublishingDate() { 75 | return publishingDate; 76 | } 77 | 78 | public void setPublishingDate(LocalDate publishingDate) { 79 | this.publishingDate = publishingDate; 80 | } 81 | 82 | public String getAuthors() { 83 | return authors; 84 | } 85 | 86 | public void setAuthors(String authors) { 87 | this.authors = authors; 88 | } 89 | 90 | @Override 91 | public String toString() { 92 | return "BookView [id=" + id + ", version=" + version + ", title=" 93 | + title + ", publishingDate=" + publishingDate + ", authors=" 94 | + authors + "]"; 95 | } 96 | } -------------------------------------------------------------------------------- /03-DatabaseViews/src/main/java/com/thorben/janssen/talk/model/Publisher.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | import jakarta.persistence.Column; 7 | import jakarta.persistence.Entity; 8 | import jakarta.persistence.GeneratedValue; 9 | import jakarta.persistence.GenerationType; 10 | import jakarta.persistence.Id; 11 | import jakarta.persistence.OneToMany; 12 | import jakarta.persistence.Version; 13 | 14 | @Entity 15 | public class Publisher { 16 | 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.AUTO) 19 | @Column(name = "id", updatable = false, nullable = false) 20 | private Long id; 21 | 22 | @Version 23 | private int version; 24 | 25 | private String name; 26 | 27 | @OneToMany(mappedBy = "publisher") 28 | private Set books = new HashSet(); 29 | 30 | public Long getId() { 31 | return this.id; 32 | } 33 | 34 | public int getVersion() { 35 | return this.version; 36 | } 37 | 38 | public String getName() { 39 | return name; 40 | } 41 | 42 | public void setName(String name) { 43 | this.name = name; 44 | } 45 | 46 | public Set getBooks() { 47 | return this.books; 48 | } 49 | 50 | public void setBooks(final Set books) { 51 | this.books = books; 52 | } 53 | 54 | @Override 55 | public boolean equals(Object obj) { 56 | if (this == obj) { 57 | return true; 58 | } 59 | if (!(obj instanceof Publisher)) { 60 | return false; 61 | } 62 | Publisher other = (Publisher) obj; 63 | if (id != null) { 64 | if (!id.equals(other.id)) { 65 | return false; 66 | } 67 | } 68 | return true; 69 | } 70 | 71 | @Override 72 | public int hashCode() { 73 | return 31; 74 | } 75 | 76 | @Override 77 | public String toString() { 78 | String result = getClass().getSimpleName() + " "; 79 | if (name != null && !name.trim().isEmpty()) 80 | result += "name: " + name; 81 | return result; 82 | } 83 | } -------------------------------------------------------------------------------- /03-DatabaseViews/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Hibernate Tips 7 | org.hibernate.jpa.HibernatePersistenceProvider 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /03-DatabaseViews/src/test/java/com/thorben/janssen/talk/TestViewEntity.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk; 2 | 3 | import java.util.List; 4 | 5 | import jakarta.persistence.EntityManager; 6 | import jakarta.persistence.EntityManagerFactory; 7 | import jakarta.persistence.Persistence; 8 | 9 | import org.apache.logging.log4j.LogManager; 10 | import org.apache.logging.log4j.Logger; 11 | import org.junit.After; 12 | import org.junit.Before; 13 | import org.junit.Test; 14 | 15 | import com.thorben.janssen.talk.model.BookView; 16 | 17 | public class TestViewEntity { 18 | 19 | Logger log = LogManager.getLogger(this.getClass().getName()); 20 | 21 | private EntityManagerFactory emf; 22 | 23 | @Before 24 | public void init() { 25 | emf = Persistence.createEntityManagerFactory("my-persistence-unit"); 26 | } 27 | 28 | @After 29 | public void close() { 30 | emf.close(); 31 | } 32 | 33 | @Test 34 | public void selectFromView() { 35 | log.info("... selectFromView ..."); 36 | 37 | EntityManager em = emf.createEntityManager(); 38 | em.getTransaction().begin(); 39 | 40 | List bvs = em.createQuery("SELECT v FROM BookView v", BookView.class) 41 | .getResultList(); 42 | 43 | for (BookView bv : bvs) { 44 | log.info(bv.getTitle() + " was written by "+bv.getAuthors()); 45 | } 46 | 47 | em.getTransaction().commit(); 48 | em.close(); 49 | } 50 | 51 | @Test 52 | public void updateView() { 53 | log.info("... updateView ..."); 54 | 55 | EntityManager em = emf.createEntityManager(); 56 | em.getTransaction().begin(); 57 | 58 | BookView bv = em.find(BookView.class, 1L); 59 | log.info(bv); 60 | // bv.setTitle("updated"); 61 | 62 | em.getTransaction().commit(); 63 | em.close(); 64 | 65 | em = emf.createEntityManager(); 66 | em.getTransaction().begin(); 67 | 68 | BookView bookupdate = em.find(BookView.class, 1L); 69 | log.info(bookupdate); 70 | 71 | em.getTransaction().commit(); 72 | em.close(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /03-DatabaseViews/src/test/resources/create-database.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE author(id bigint NOT NULL, firstname character varying(255), lastname character varying(255), version integer NOT NULL, CONSTRAINT author_pkey PRIMARY KEY (id)); 2 | 3 | CREATE TABLE book(id bigint NOT NULL, publishingdate date, title character varying(255), version integer, CONSTRAINT book_pkey PRIMARY KEY (id)); 4 | 5 | CREATE TABLE bookauthor(bookid bigint NOT NULL, authorid bigint NOT NULL, CONSTRAINT bookauthor_pkey PRIMARY KEY (bookid, authorid), CONSTRAINT fk1vpkcbic0iljxqxu629o36mpc FOREIGN KEY (bookid) REFERENCES book (id)); 6 | 7 | CREATE OR REPLACE VIEW bookview AS SELECT b.id, b.publishingdate, b.title, b.version, string_agg(a.name, ', '::text) AS authors FROM book b JOIN ( SELECT (a_1.firstname::text || ' '::text) || a_1.lastname::text AS name, b_1.id AS bookid FROM book b_1 JOIN bookauthor ba ON b_1.id = ba.bookid JOIN author a_1 ON a_1.id = ba.authorid) a ON a.bookid = b.id GROUP BY b.id; -------------------------------------------------------------------------------- /03-DatabaseViews/src/test/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO author (id, firstname, lastname, version) VALUES (1, 'Thorben', 'Janssen', 0); 2 | 3 | INSERT INTO book (id, publishingdate, title, version) VALUES (1, '2017-04-04', 'Hibernate Tips', 0); 4 | 5 | INSERT INTO bookauthor (bookid, authorid) VALUES (1, 1); 6 | -------------------------------------------------------------------------------- /03-DatabaseViews/src/test/resources/drop-database.sql: -------------------------------------------------------------------------------- 1 | drop table if exists BookAuthor cascade 2 | drop table if exists Author cascade 3 | drop table if exists Book cascade 4 | drop table if exists Publisher cascade -------------------------------------------------------------------------------- /03-DatabaseViews/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 2 | log4j.appender.stdout.Target=System.out 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n 5 | 6 | log4j.rootLogger=info, stdout 7 | # basic log level for all messages 8 | log4j.logger.org.hibernate=info 9 | 10 | # SQL statements and parameters 11 | log4j.logger.org.hibernate.SQL=debug -------------------------------------------------------------------------------- /03-DatabaseViews/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /04-OrderAssociation/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /04-OrderAssociation/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | jar 7 | 8 | 9 | org.hibernate.orm 10 | hibernate-core 11 | 12 | 13 | junit 14 | junit 15 | test 16 | 17 | 18 | org.postgresql 19 | postgresql 20 | test 21 | 22 | 23 | org.apache.logging.log4j 24 | log4j-api 25 | 26 | 27 | org.apache.logging.log4j 28 | log4j-core 29 | test 30 | 31 | 32 | 05-OrderAssociation 33 | 34 | com.thorben.janssen.talks 35 | HibernateTips 36 | 1.0.0-SNAPSHOT 37 | .. 38 | 39 | 40 | -------------------------------------------------------------------------------- /04-OrderAssociation/src/main/java/com/thorben/janssen/talk/model/Author.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import jakarta.persistence.Column; 7 | import jakarta.persistence.Entity; 8 | import jakarta.persistence.GeneratedValue; 9 | import jakarta.persistence.GenerationType; 10 | import jakarta.persistence.Id; 11 | import jakarta.persistence.ManyToMany; 12 | import jakarta.persistence.Version; 13 | 14 | @Entity 15 | public class Author { 16 | 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.AUTO) 19 | @Column(name = "id", updatable = false, nullable = false) 20 | private Long id; 21 | 22 | @Version 23 | private int version; 24 | 25 | private String firstName; 26 | 27 | private String lastName; 28 | 29 | @ManyToMany(mappedBy="authors") 30 | private List books = new ArrayList(); 31 | 32 | public Long getId() { 33 | return this.id; 34 | } 35 | 36 | public int getVersion() { 37 | return this.version; 38 | } 39 | 40 | public String getFirstName() { 41 | return firstName; 42 | } 43 | 44 | public void setFirstName(String firstName) { 45 | this.firstName = firstName; 46 | } 47 | 48 | public String getLastName() { 49 | return lastName; 50 | } 51 | 52 | public void setLastName(String lastName) { 53 | this.lastName = lastName; 54 | } 55 | 56 | public List getBooks() { 57 | return this.books; 58 | } 59 | 60 | public void setBooks(final List books) { 61 | this.books = books; 62 | } 63 | 64 | @Override 65 | public boolean equals(Object obj) { 66 | if (this == obj) { 67 | return true; 68 | } 69 | if (!(obj instanceof Author)) { 70 | return false; 71 | } 72 | Author other = (Author) obj; 73 | if (id != null) { 74 | if (!id.equals(other.id)) { 75 | return false; 76 | } 77 | } 78 | return true; 79 | } 80 | 81 | @Override 82 | public int hashCode() { 83 | return 31; 84 | } 85 | 86 | @Override 87 | public String toString() { 88 | String result = getClass().getSimpleName() + " "; 89 | if (firstName != null && !firstName.trim().isEmpty()) 90 | result += "firstName: " + firstName; 91 | if (lastName != null && !lastName.trim().isEmpty()) 92 | result += ", lastName: " + lastName; 93 | return result; 94 | } 95 | } -------------------------------------------------------------------------------- /04-OrderAssociation/src/main/java/com/thorben/janssen/talk/model/Book.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.time.LocalDate; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | import jakarta.persistence.Entity; 8 | import jakarta.persistence.GeneratedValue; 9 | import jakarta.persistence.GenerationType; 10 | import jakarta.persistence.Id; 11 | import jakarta.persistence.JoinColumn; 12 | import jakarta.persistence.JoinTable; 13 | import jakarta.persistence.ManyToMany; 14 | import jakarta.persistence.ManyToOne; 15 | import jakarta.persistence.OrderBy; 16 | import jakarta.persistence.Version; 17 | 18 | @Entity 19 | public class Book { 20 | 21 | @Id 22 | @GeneratedValue(strategy = GenerationType.SEQUENCE) 23 | private Long id; 24 | 25 | @Version 26 | private int version; 27 | 28 | private String title; 29 | 30 | private LocalDate publishingDate; 31 | 32 | @ManyToOne 33 | @JoinColumn(name="publisherid") 34 | private Publisher publisher; 35 | 36 | @ManyToMany 37 | @JoinTable( 38 | name="BookAuthor", 39 | joinColumns={@JoinColumn(name="bookId", referencedColumnName="id")}, 40 | inverseJoinColumns={@JoinColumn(name="authorId", referencedColumnName="id")}) 41 | @OrderBy(value = "lastName ASC, firstName ASC") 42 | private Set authors = new HashSet(); 43 | 44 | public Long getId() { 45 | return this.id; 46 | } 47 | 48 | public int getVersion() { 49 | return this.version; 50 | } 51 | 52 | public String getTitle() { 53 | return title; 54 | } 55 | 56 | public void setTitle(String title) { 57 | this.title = title; 58 | } 59 | 60 | public LocalDate getPublishingDate() { 61 | return publishingDate; 62 | } 63 | 64 | public void setPublishingDate(LocalDate publishingDate) { 65 | this.publishingDate = publishingDate; 66 | } 67 | 68 | public Publisher getPublisher() { 69 | return this.publisher; 70 | } 71 | 72 | public void setPublisher(final Publisher publisher) { 73 | this.publisher = publisher; 74 | } 75 | 76 | public Set getAuthors() { 77 | return authors; 78 | } 79 | 80 | public void setAuthors(Set authors) { 81 | this.authors = authors; 82 | } 83 | 84 | @Override 85 | public boolean equals(Object obj) { 86 | if (this == obj) { 87 | return true; 88 | } 89 | if (!(obj instanceof Book)) { 90 | return false; 91 | } 92 | Book other = (Book) obj; 93 | if (id != null) { 94 | if (!id.equals(other.id)) { 95 | return false; 96 | } 97 | } 98 | return true; 99 | } 100 | 101 | @Override 102 | public int hashCode() { 103 | return 31; 104 | } 105 | 106 | @Override 107 | public String toString() { 108 | String result = getClass().getSimpleName() + " "; 109 | if (title != null && !title.trim().isEmpty()) 110 | result += "title: " + title; 111 | return result; 112 | } 113 | } -------------------------------------------------------------------------------- /04-OrderAssociation/src/main/java/com/thorben/janssen/talk/model/Publisher.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | import jakarta.persistence.Column; 7 | import jakarta.persistence.Entity; 8 | import jakarta.persistence.GeneratedValue; 9 | import jakarta.persistence.GenerationType; 10 | import jakarta.persistence.Id; 11 | import jakarta.persistence.OneToMany; 12 | import jakarta.persistence.Version; 13 | 14 | @Entity 15 | public class Publisher { 16 | 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.AUTO) 19 | @Column(name = "id", updatable = false, nullable = false) 20 | private Long id; 21 | 22 | @Version 23 | private int version; 24 | 25 | private String name; 26 | 27 | @OneToMany(mappedBy = "publisher") 28 | private Set books = new HashSet(); 29 | 30 | public Long getId() { 31 | return this.id; 32 | } 33 | 34 | public int getVersion() { 35 | return this.version; 36 | } 37 | 38 | public String getName() { 39 | return name; 40 | } 41 | 42 | public void setName(String name) { 43 | this.name = name; 44 | } 45 | 46 | public Set getBooks() { 47 | return this.books; 48 | } 49 | 50 | public void setBooks(final Set books) { 51 | this.books = books; 52 | } 53 | 54 | @Override 55 | public boolean equals(Object obj) { 56 | if (this == obj) { 57 | return true; 58 | } 59 | if (!(obj instanceof Publisher)) { 60 | return false; 61 | } 62 | Publisher other = (Publisher) obj; 63 | if (id != null) { 64 | if (!id.equals(other.id)) { 65 | return false; 66 | } 67 | } 68 | return true; 69 | } 70 | 71 | @Override 72 | public int hashCode() { 73 | return 31; 74 | } 75 | 76 | @Override 77 | public String toString() { 78 | String result = getClass().getSimpleName() + " "; 79 | if (name != null && !name.trim().isEmpty()) 80 | result += "name: " + name; 81 | return result; 82 | } 83 | } -------------------------------------------------------------------------------- /04-OrderAssociation/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Hibernate Tips 7 | org.hibernate.jpa.HibernatePersistenceProvider 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /04-OrderAssociation/src/test/java/com/thorben/janssen/talk/TestOrderRelationships.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.junit.After; 6 | import org.junit.Assert; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | 10 | import com.thorben.janssen.talk.model.Author; 11 | import com.thorben.janssen.talk.model.Book; 12 | 13 | import jakarta.persistence.EntityManager; 14 | import jakarta.persistence.EntityManagerFactory; 15 | import jakarta.persistence.Persistence; 16 | 17 | public class TestOrderRelationships { 18 | 19 | Logger log = LogManager.getLogger(this.getClass().getName()); 20 | 21 | private EntityManagerFactory emf; 22 | 23 | @Before 24 | public void init() { 25 | emf = Persistence.createEntityManagerFactory("my-persistence-unit"); 26 | } 27 | 28 | @After 29 | public void close() { 30 | emf.close(); 31 | } 32 | 33 | @Test 34 | public void orderAuthors() { 35 | log.info("... orderAuthors ..."); 36 | 37 | EntityManager em = emf.createEntityManager(); 38 | em.getTransaction().begin(); 39 | 40 | Book b = em.find(Book.class, 2L); 41 | 42 | Author[] authors = b.getAuthors().toArray(new Author[3]); 43 | Assert.assertEquals("Bauer", authors[0].getLastName()); 44 | Assert.assertEquals("Gregory", authors[1].getLastName()); 45 | Assert.assertEquals("King", authors[2].getLastName()); 46 | for (Author a : authors) { 47 | log.info(a.getLastName() + ", id: " + a.getId()); 48 | } 49 | 50 | em.getTransaction().commit(); 51 | em.close(); 52 | } 53 | 54 | @Test 55 | public void fetchBooksAndAuthors() { 56 | log.info("... fetchBooksAndAuthors ..."); 57 | 58 | EntityManager em = emf.createEntityManager(); 59 | em.getTransaction().begin(); 60 | 61 | Book b = em.createQuery("SELECT b FROM Book b JOIN FETCH b.authors a WHERE b.id = 2", Book.class).getSingleResult(); 62 | Author[] authors = b.getAuthors().toArray(new Author[3]); 63 | Assert.assertEquals("Bauer", authors[0].getLastName()); 64 | Assert.assertEquals("Gregory", authors[1].getLastName()); 65 | Assert.assertEquals("King", authors[2].getLastName()); 66 | for (Author a : authors) { 67 | log.info(a.getLastName() + ", id: " + a.getId()); 68 | } 69 | 70 | em.getTransaction().commit(); 71 | em.close(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /04-OrderAssociation/src/test/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO author (id, firstname, lastname, version) VALUES (1, 'Joshua', 'Bloch', 0); 2 | INSERT INTO author (id, firstname, lastname, version) VALUES (2, 'Gavin', 'King', 0); 3 | INSERT INTO author (id, firstname, lastname, version) VALUES (3, 'Christian', 'Bauer', 0); 4 | INSERT INTO author (id, firstname, lastname, version) VALUES (4, 'Gary', 'Gregory', 0); 5 | INSERT INTO author (id, firstname, lastname, version) VALUES (5, 'Raoul-Gabriel', 'Urma', 0); 6 | INSERT INTO author (id, firstname, lastname, version) VALUES (6, 'Mario', 'Fusco', 0); 7 | INSERT INTO author (id, firstname, lastname, version) VALUES (7, 'Alan', 'Mycroft', 0); 8 | INSERT INTO author (id, firstname, lastname, version) VALUES (8, 'Andrew Lee', 'Rubinger', 0); 9 | INSERT INTO author (id, firstname, lastname, version) VALUES (9, 'Aslak', 'Knutsen', 0); 10 | INSERT INTO author (id, firstname, lastname, version) VALUES (10, 'Bill', 'Burke', 0); 11 | INSERT INTO author (id, firstname, lastname, version) VALUES (11, 'Scott', 'Oaks', 0); 12 | 13 | INSERT INTO book (id, publishingdate, title, version) VALUES (1, '2008-05-08', 'Effective Java', 0); 14 | INSERT INTO book (id, publishingdate, title, version) VALUES (2, '2015-10-01', 'Java Persistence with Hibernate', 0); 15 | INSERT INTO book (id, publishingdate, title, version) VALUES (3, '2014-08-28', 'Java 8 in Action', 0); 16 | INSERT INTO book (id, publishingdate, title, version) VALUES (4, '2014-03-12', 'Continuous Enterprise Development in Java', 0); 17 | INSERT INTO book (id, publishingdate, title, version) VALUES (5, '2010-09-08', 'Enterprise JavaBeans 3.1', 0); 18 | INSERT INTO book (id, publishingdate, title, version) VALUES (6, '2014-04-29', 'Java Performance The Definitive Guide', 0); 19 | 20 | INSERT INTO bookauthor (bookid, authorid) VALUES (1, 1); 21 | INSERT INTO bookauthor (bookid, authorid) VALUES (2, 2); 22 | INSERT INTO bookauthor (bookid, authorid) VALUES (2, 3); 23 | INSERT INTO bookauthor (bookid, authorid) VALUES (2, 4); 24 | INSERT INTO bookauthor (bookid, authorid) VALUES (3, 5); 25 | INSERT INTO bookauthor (bookid, authorid) VALUES (3, 6); 26 | INSERT INTO bookauthor (bookid, authorid) VALUES (3, 7); 27 | INSERT INTO bookauthor (bookid, authorid) VALUES (4, 8); 28 | INSERT INTO bookauthor (bookid, authorid) VALUES (4, 9); 29 | INSERT INTO bookauthor (bookid, authorid) VALUES (5, 8); 30 | INSERT INTO bookauthor (bookid, authorid) VALUES (5, 10); 31 | INSERT INTO bookauthor (bookid, authorid) VALUES (6, 11); 32 | -------------------------------------------------------------------------------- /04-OrderAssociation/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 2 | log4j.appender.stdout.Target=System.out 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n 5 | 6 | log4j.rootLogger=info, stdout 7 | # basic log level for all messages 8 | log4j.logger.org.hibernate=info 9 | 10 | # SQL statements and parameters 11 | log4j.logger.org.hibernate.SQL=debug 12 | #log4j.logger.org.hibernate.type.descriptor.sql=trace -------------------------------------------------------------------------------- /04-OrderAssociation/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /05-KeepAssociationOrder/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /05-KeepAssociationOrder/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | jar 7 | 8 | 9 | org.hibernate.orm 10 | hibernate-core 11 | 12 | 13 | junit 14 | junit 15 | test 16 | 17 | 18 | org.postgresql 19 | postgresql 20 | test 21 | 22 | 23 | org.apache.logging.log4j 24 | log4j-api 25 | 26 | 27 | org.apache.logging.log4j 28 | log4j-core 29 | test 30 | 31 | 32 | 06-KeepAssociationOrder 33 | 34 | com.thorben.janssen.talks 35 | HibernateTips 36 | 1.0.0-SNAPSHOT 37 | .. 38 | 39 | 40 | -------------------------------------------------------------------------------- /05-KeepAssociationOrder/src/main/java/com/thorben/janssen/talk/model/Author.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import jakarta.persistence.Entity; 7 | import jakarta.persistence.GeneratedValue; 8 | import jakarta.persistence.GenerationType; 9 | import jakarta.persistence.Id; 10 | import jakarta.persistence.ManyToMany; 11 | import jakarta.persistence.Version; 12 | 13 | @Entity 14 | public class Author { 15 | 16 | @Id 17 | @GeneratedValue(strategy = GenerationType.SEQUENCE) 18 | private Long id; 19 | 20 | @Version 21 | private int version; 22 | 23 | private String firstName; 24 | 25 | private String lastName; 26 | 27 | @ManyToMany(mappedBy = "authors") 28 | private List books = new ArrayList(); 29 | 30 | public Long getId() { 31 | return this.id; 32 | } 33 | 34 | public int getVersion() { 35 | return this.version; 36 | } 37 | 38 | public String getFirstName() { 39 | return firstName; 40 | } 41 | 42 | public void setFirstName(String firstName) { 43 | this.firstName = firstName; 44 | } 45 | 46 | public String getLastName() { 47 | return lastName; 48 | } 49 | 50 | public void setLastName(String lastName) { 51 | this.lastName = lastName; 52 | } 53 | 54 | public List getBooks() { 55 | return this.books; 56 | } 57 | 58 | public void setBooks(final List books) { 59 | this.books = books; 60 | } 61 | 62 | @Override 63 | public String toString() { 64 | String result = getClass().getSimpleName() + " "; 65 | if (firstName != null && !firstName.trim().isEmpty()) 66 | result += "firstName: " + firstName; 67 | if (lastName != null && !lastName.trim().isEmpty()) 68 | result += ", lastName: " + lastName; 69 | return result; 70 | } 71 | } -------------------------------------------------------------------------------- /05-KeepAssociationOrder/src/main/java/com/thorben/janssen/talk/model/Book.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.time.LocalDate; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import jakarta.persistence.Entity; 8 | import jakarta.persistence.GeneratedValue; 9 | import jakarta.persistence.GenerationType; 10 | import jakarta.persistence.Id; 11 | import jakarta.persistence.JoinColumn; 12 | import jakarta.persistence.JoinTable; 13 | import jakarta.persistence.ManyToMany; 14 | import jakarta.persistence.OrderColumn; 15 | import jakarta.persistence.Version; 16 | 17 | @Entity 18 | public class Book { 19 | 20 | @Id 21 | @GeneratedValue(strategy = GenerationType.SEQUENCE) 22 | private Long id; 23 | 24 | @Version 25 | private int version; 26 | 27 | private String title; 28 | 29 | private LocalDate publishingDate; 30 | 31 | @ManyToMany 32 | @JoinTable( 33 | name="BookAuthor", 34 | joinColumns={@JoinColumn(name="bookId", referencedColumnName="id")}, 35 | inverseJoinColumns={@JoinColumn(name="authorId", referencedColumnName="id")}) 36 | @OrderColumn 37 | private List authors = new ArrayList(); 38 | 39 | public Long getId() { 40 | return this.id; 41 | } 42 | 43 | public int getVersion() { 44 | return this.version; 45 | } 46 | 47 | public String getTitle() { 48 | return title; 49 | } 50 | 51 | public void setTitle(String title) { 52 | this.title = title; 53 | } 54 | 55 | public LocalDate getPublishingDate() { 56 | return publishingDate; 57 | } 58 | 59 | public void setPublishingDate(LocalDate publishingDate) { 60 | this.publishingDate = publishingDate; 61 | } 62 | 63 | public List getAuthors() { 64 | return authors; 65 | } 66 | 67 | public void setAuthors(List authors) { 68 | this.authors = authors; 69 | } 70 | 71 | @Override 72 | public boolean equals(Object obj) { 73 | if (this == obj) { 74 | return true; 75 | } 76 | if (!(obj instanceof Book)) { 77 | return false; 78 | } 79 | Book other = (Book) obj; 80 | if (id != null) { 81 | if (!id.equals(other.id)) { 82 | return false; 83 | } 84 | } 85 | return true; 86 | } 87 | 88 | @Override 89 | public int hashCode() { 90 | return 31; 91 | } 92 | 93 | @Override 94 | public String toString() { 95 | String result = getClass().getSimpleName() + " "; 96 | if (title != null && !title.trim().isEmpty()) 97 | result += "title: " + title; 98 | return result; 99 | } 100 | } -------------------------------------------------------------------------------- /05-KeepAssociationOrder/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Hibernate Tips 7 | org.hibernate.jpa.HibernatePersistenceProvider 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /05-KeepAssociationOrder/src/test/java/com/thorben/janssen/talk/TestOrderRelationships.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.junit.After; 6 | import org.junit.Assert; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | 10 | import com.thorben.janssen.talk.model.Author; 11 | import com.thorben.janssen.talk.model.Book; 12 | 13 | import jakarta.persistence.EntityManager; 14 | import jakarta.persistence.EntityManagerFactory; 15 | import jakarta.persistence.Persistence; 16 | 17 | public class TestOrderRelationships { 18 | 19 | Logger log = LogManager.getLogger(this.getClass().getName()); 20 | 21 | private EntityManagerFactory emf; 22 | 23 | @Before 24 | public void init() { 25 | emf = Persistence.createEntityManagerFactory("my-persistence-unit"); 26 | } 27 | 28 | @After 29 | public void close() { 30 | emf.close(); 31 | } 32 | 33 | @Test 34 | public void orderAuthors() { 35 | log.info("... orderAuthors ..."); 36 | 37 | EntityManager em = emf.createEntityManager(); 38 | em.getTransaction().begin(); 39 | 40 | Book b = new Book(); 41 | b.setTitle("My Book"); 42 | em.persist(b); 43 | 44 | Author a1 = new Author(); 45 | a1.setFirstName("Author 1"); 46 | em.persist(a1); 47 | 48 | Author a2 = new Author(); 49 | a2.setFirstName("Author 2"); 50 | em.persist(a2); 51 | 52 | a2.getBooks().add(b); 53 | b.getAuthors().add(a2); 54 | a1.getBooks().add(b); 55 | b.getAuthors().add(a1); 56 | 57 | em.getTransaction().commit(); 58 | em.close(); 59 | 60 | em = emf.createEntityManager(); 61 | em.getTransaction().begin(); 62 | 63 | b = em.find(Book.class, b.getId()); 64 | 65 | Author[] authors = b.getAuthors().toArray(new Author[2]); 66 | Assert.assertEquals("Author 2", authors[0].getFirstName()); 67 | Assert.assertEquals("Author 1", authors[1].getFirstName()); 68 | for (Author a : authors) { 69 | log.info(a.getLastName() + ", id: " + a.getId()); 70 | } 71 | 72 | em.getTransaction().commit(); 73 | em.close(); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /05-KeepAssociationOrder/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 2 | log4j.appender.stdout.Target=System.out 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n 5 | 6 | log4j.rootLogger=info, stdout 7 | # basic log level for all messages 8 | log4j.logger.org.hibernate=info 9 | 10 | # SQL statements and parameters 11 | log4j.logger.org.hibernate.SQL=debug 12 | #log4j.logger.org.hibernate.type.descriptor.sql=trace -------------------------------------------------------------------------------- /05-KeepAssociationOrder/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /06-PrimaryKeyUuid/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /06-PrimaryKeyUuid/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | jar 7 | 8 | 9 | org.hibernate.orm 10 | hibernate-core 11 | 12 | 13 | junit 14 | junit 15 | test 16 | 17 | 18 | org.postgresql 19 | postgresql 20 | test 21 | 22 | 23 | org.apache.logging.log4j 24 | log4j-api 25 | 26 | 27 | org.apache.logging.log4j 28 | log4j-core 29 | test 30 | 31 | 32 | jakarta.xml.bind 33 | jakarta.xml.bind-api 34 | 35 | 36 | 07-EmbeddableRecord 37 | 38 | com.thorben.janssen.talks 39 | HibernateTips 40 | 1.0.0-SNAPSHOT 41 | .. 42 | 43 | -------------------------------------------------------------------------------- /06-PrimaryKeyUuid/src/main/java/com/thorben/janssen/talk/model/Author.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.util.UUID; 4 | 5 | import org.hibernate.annotations.GenericGenerator; 6 | import org.hibernate.annotations.Parameter; 7 | 8 | import jakarta.persistence.Entity; 9 | import jakarta.persistence.GeneratedValue; 10 | import jakarta.persistence.Id; 11 | import jakarta.persistence.Version; 12 | 13 | @Entity 14 | public class Author { 15 | 16 | @Id 17 | @GeneratedValue 18 | // @GeneratedValue(generator = "UUID") 19 | // @GenericGenerator( 20 | // name = "UUID", 21 | // strategy = "org.hibernate.id.UUIDGenerator", 22 | // parameters = { 23 | // @Parameter( 24 | // name = "uuid_gen_strategy_class", 25 | // value = "org.hibernate.id.uuid.CustomVersionOneStrategy" 26 | // ) 27 | // } 28 | // ) 29 | private UUID id; 30 | 31 | @Version 32 | private int version; 33 | 34 | private String firstName; 35 | 36 | private String lastName; 37 | 38 | public UUID getId() { 39 | return this.id; 40 | } 41 | 42 | public int getVersion() { 43 | return this.version; 44 | } 45 | 46 | public String getFirstName() { 47 | return firstName; 48 | } 49 | 50 | public void setFirstName(String firstName) { 51 | this.firstName = firstName; 52 | } 53 | 54 | public String getLastName() { 55 | return lastName; 56 | } 57 | 58 | public void setLastName(String lastName) { 59 | this.lastName = lastName; 60 | } 61 | 62 | @Override 63 | public boolean equals(Object obj) { 64 | if (this == obj) { 65 | return true; 66 | } 67 | if (!(obj instanceof Author)) { 68 | return false; 69 | } 70 | Author other = (Author) obj; 71 | if (id != null) { 72 | if (!id.equals(other.id)) { 73 | return false; 74 | } 75 | } 76 | return true; 77 | } 78 | 79 | @Override 80 | public int hashCode() { 81 | return 31; 82 | } 83 | 84 | @Override 85 | public String toString() { 86 | String result = getClass().getSimpleName() + " "; 87 | if (firstName != null && !firstName.trim().isEmpty()) { 88 | result += "firstName: " + firstName; 89 | } 90 | if (lastName != null && !lastName.trim().isEmpty()) { 91 | result += ", lastName: " + lastName; 92 | } 93 | return result; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /06-PrimaryKeyUuid/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Hibernate Tips 7 | org.hibernate.jpa.HibernatePersistenceProvider 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /06-PrimaryKeyUuid/src/test/java/com/thorben/janssen/talk/TestUUIDPrimaryKey.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk; 2 | 3 | import java.util.UUID; 4 | 5 | import org.apache.logging.log4j.LogManager; 6 | import org.apache.logging.log4j.Logger; 7 | import org.junit.After; 8 | import org.junit.Assert; 9 | import org.junit.Before; 10 | import org.junit.Test; 11 | 12 | import com.thorben.janssen.talk.model.Author; 13 | 14 | import jakarta.persistence.EntityManager; 15 | import jakarta.persistence.EntityManagerFactory; 16 | import jakarta.persistence.Persistence; 17 | 18 | public class TestUUIDPrimaryKey { 19 | 20 | Logger log = LogManager.getLogger(this.getClass().getName()); 21 | 22 | private EntityManagerFactory emf; 23 | 24 | @Before 25 | public void init() { 26 | emf = Persistence.createEntityManagerFactory("my-persistence-unit"); 27 | } 28 | 29 | @After 30 | public void close() { 31 | emf.close(); 32 | } 33 | 34 | @Test 35 | public void testUUIDPrimaryKeyV4() { 36 | log.info("... testUUIDPrimaryKeyV4 ..."); 37 | 38 | EntityManager em = emf.createEntityManager(); 39 | em.getTransaction().begin(); 40 | 41 | Author a = new Author(); 42 | a.setFirstName("Thorben"); 43 | a.setLastName("Janssen"); 44 | 45 | log.info("Persist new Author entity."); 46 | em.persist(a); 47 | 48 | em.getTransaction().commit(); 49 | em.close(); 50 | 51 | em = emf.createEntityManager(); 52 | em.getTransaction().begin(); 53 | 54 | UUID uuid = a.getId(); 55 | 56 | a = em.find(Author.class, uuid); 57 | Assert.assertEquals(uuid, a.getId()); 58 | 59 | em.getTransaction().commit(); 60 | em.close(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /06-PrimaryKeyUuid/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 2 | log4j.appender.stdout.Target=System.out 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n 5 | 6 | log4j.rootLogger=info, stdout 7 | # basic log level for all messages 8 | log4j.logger.org.hibernate=info 9 | 10 | # SQL statements and parameters 11 | log4j.logger.org.hibernate.SQL=debug 12 | log4j.logger.org.hibernate.type.descriptor.sql=trace 13 | log4j.logger.org.hibernate.event.internal.AbstractSaveEventListener=trace -------------------------------------------------------------------------------- /06-PrimaryKeyUuid/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /07-MapOptionalAssociations/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /07-MapOptionalAssociations/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | jar 7 | 8 | 9 | org.hibernate.orm 10 | hibernate-core 11 | 12 | 13 | junit 14 | junit 15 | test 16 | 17 | 18 | org.postgresql 19 | postgresql 20 | test 21 | 22 | 23 | org.apache.logging.log4j 24 | log4j-api 25 | 26 | 27 | org.apache.logging.log4j 28 | log4j-core 29 | test 30 | 31 | 32 | 08-MapOptionalAssociations 33 | 34 | com.thorben.janssen.talks 35 | HibernateTips 36 | 1.0.0-SNAPSHOT 37 | .. 38 | 39 | 40 | -------------------------------------------------------------------------------- /07-MapOptionalAssociations/src/main/java/com/thorben/janssen/talk/model/Book.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.time.LocalDate; 4 | import java.util.Optional; 5 | 6 | import jakarta.persistence.Entity; 7 | import jakarta.persistence.GeneratedValue; 8 | import jakarta.persistence.GenerationType; 9 | import jakarta.persistence.Id; 10 | import jakarta.persistence.JoinColumn; 11 | import jakarta.persistence.ManyToOne; 12 | import jakarta.persistence.Version; 13 | 14 | @Entity 15 | public class Book { 16 | 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.SEQUENCE) 19 | private Long id; 20 | 21 | @Version 22 | private int version; 23 | 24 | private String title; 25 | 26 | private LocalDate publishingDate; 27 | 28 | @ManyToOne 29 | @JoinColumn(name = "publisherid") 30 | private Publisher publisher; 31 | 32 | public Long getId() { 33 | return this.id; 34 | } 35 | 36 | public int getVersion() { 37 | return this.version; 38 | } 39 | 40 | public String getTitle() { 41 | return title; 42 | } 43 | 44 | public void setTitle(String title) { 45 | this.title = title; 46 | } 47 | 48 | public LocalDate getPublishingDate() { 49 | return publishingDate; 50 | } 51 | 52 | public void setPublishingDate(LocalDate publishingDate) { 53 | this.publishingDate = publishingDate; 54 | } 55 | 56 | public Optional getPublisher() { 57 | return Optional.ofNullable(this.publisher); 58 | } 59 | 60 | public void setPublisher(final Publisher publisher) { 61 | this.publisher = publisher; 62 | } 63 | 64 | @Override 65 | public boolean equals(Object obj) { 66 | if (this == obj) { 67 | return true; 68 | } 69 | if (!(obj instanceof Book)) { 70 | return false; 71 | } 72 | Book other = (Book) obj; 73 | if (id != null) { 74 | if (!id.equals(other.id)) { 75 | return false; 76 | } 77 | } 78 | return true; 79 | } 80 | 81 | @Override 82 | public int hashCode() { 83 | return 31; 84 | } 85 | 86 | @Override 87 | public String toString() { 88 | String result = getClass().getSimpleName() + " "; 89 | if (title != null && !title.trim().isEmpty()) { 90 | result += "title: " + title; 91 | } 92 | return result; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /07-MapOptionalAssociations/src/main/java/com/thorben/janssen/talk/model/Publisher.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | import jakarta.persistence.Column; 7 | import jakarta.persistence.Entity; 8 | import jakarta.persistence.GeneratedValue; 9 | import jakarta.persistence.GenerationType; 10 | import jakarta.persistence.Id; 11 | import jakarta.persistence.OneToMany; 12 | import jakarta.persistence.Version; 13 | 14 | @Entity 15 | public class Publisher { 16 | 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.AUTO) 19 | @Column(name = "id", updatable = false, nullable = false) 20 | private Long id; 21 | 22 | @Version 23 | private int version; 24 | 25 | private String name; 26 | 27 | @OneToMany(mappedBy = "publisher") 28 | private Set books = new HashSet(); 29 | 30 | public Long getId() { 31 | return this.id; 32 | } 33 | 34 | public int getVersion() { 35 | return this.version; 36 | } 37 | 38 | public String getName() { 39 | return name; 40 | } 41 | 42 | public void setName(String name) { 43 | this.name = name; 44 | } 45 | 46 | public Set getBooks() { 47 | return this.books; 48 | } 49 | 50 | public void setBooks(final Set books) { 51 | this.books = books; 52 | } 53 | 54 | @Override 55 | public boolean equals(Object obj) { 56 | if (this == obj) { 57 | return true; 58 | } 59 | if (!(obj instanceof Publisher)) { 60 | return false; 61 | } 62 | Publisher other = (Publisher) obj; 63 | if (id != null) { 64 | if (!id.equals(other.id)) { 65 | return false; 66 | } 67 | } 68 | return true; 69 | } 70 | 71 | @Override 72 | public int hashCode() { 73 | return 31; 74 | } 75 | 76 | @Override 77 | public String toString() { 78 | String result = getClass().getSimpleName() + " "; 79 | if (name != null && !name.trim().isEmpty()) 80 | result += "name: " + name; 81 | return result; 82 | } 83 | } -------------------------------------------------------------------------------- /07-MapOptionalAssociations/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Hibernate Tips 7 | org.hibernate.jpa.HibernatePersistenceProvider 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /07-MapOptionalAssociations/src/test/java/com/thorben/janssen/talk/TestMapOptionalAssociation.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.junit.After; 6 | import org.junit.Assert; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | 10 | import com.thorben.janssen.talk.model.Book; 11 | 12 | import jakarta.persistence.EntityManager; 13 | import jakarta.persistence.EntityManagerFactory; 14 | import jakarta.persistence.Persistence; 15 | 16 | public class TestMapOptionalAssociation { 17 | 18 | Logger log = LogManager.getLogger(this.getClass().getName()); 19 | 20 | private EntityManagerFactory emf; 21 | 22 | @Before 23 | public void init() { 24 | emf = Persistence.createEntityManagerFactory("my-persistence-unit"); 25 | } 26 | 27 | @After 28 | public void close() { 29 | emf.close(); 30 | } 31 | 32 | @Test 33 | public void testOptional() { 34 | log.info("... testOptional ..."); 35 | 36 | EntityManager em = emf.createEntityManager(); 37 | em.getTransaction().begin(); 38 | 39 | Book b = em.find(Book.class, 1L); 40 | Assert.assertTrue(b.getPublisher().isPresent()); 41 | log.info(b.getTitle() + " was published by " + b.getPublisher().get().getName()); 42 | 43 | b = em.find(Book.class, 2L); 44 | Assert.assertFalse(b.getPublisher().isPresent()); 45 | log.info(b.getTitle() + " has no publisher"); 46 | 47 | em.getTransaction().commit(); 48 | em.close(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /07-MapOptionalAssociations/src/test/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO publisher(id, name, version) VALUES (1, 'Manning Publications', 0) 2 | 3 | INSERT INTO book (id, publishingdate, title, publisherid, version) VALUES (1, '2015-10-01', 'Java Persistence with Hibernate', 1, 0); 4 | INSERT INTO book (id, publishingdate, title, version) VALUES (2, '2017-02-01', 'Hibernate Tips', 0); -------------------------------------------------------------------------------- /07-MapOptionalAssociations/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 2 | log4j.appender.stdout.Target=System.out 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n 5 | 6 | log4j.rootLogger=info, stdout 7 | # basic log level for all messages 8 | log4j.logger.org.hibernate=info 9 | 10 | # SQL statements and parameters 11 | log4j.logger.org.hibernate.SQL=debug 12 | #log4j.logger.org.hibernate.type.descriptor.sql=trace -------------------------------------------------------------------------------- /07-MapOptionalAssociations/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /08-EmbeddableRecord/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /08-EmbeddableRecord/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | jar 7 | 8 | 9 | org.hibernate.orm 10 | hibernate-core 11 | 12 | 13 | junit 14 | junit 15 | test 16 | 17 | 18 | org.postgresql 19 | postgresql 20 | test 21 | 22 | 23 | org.apache.logging.log4j 24 | log4j-api 25 | 26 | 27 | org.apache.logging.log4j 28 | log4j-core 29 | test 30 | 31 | 32 | jakarta.xml.bind 33 | jakarta.xml.bind-api 34 | 35 | 36 | 09-PrimaryKeyRecord 37 | 38 | com.thorben.janssen.talks 39 | HibernateTips 40 | 1.0.0-SNAPSHOT 41 | .. 42 | 43 | -------------------------------------------------------------------------------- /08-EmbeddableRecord/src/main/java/com/thorben/janssen/talk/model/Address.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import org.hibernate.annotations.EmbeddableInstantiator; 4 | 5 | import jakarta.persistence.Embeddable; 6 | 7 | @Embeddable 8 | @EmbeddableInstantiator(AddressInstantiator.class) 9 | public record Address (String street, String city, String postalCode) {} -------------------------------------------------------------------------------- /08-EmbeddableRecord/src/main/java/com/thorben/janssen/talk/model/AddressInstantiator.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import org.hibernate.engine.spi.SessionFactoryImplementor; 4 | import org.hibernate.metamodel.spi.EmbeddableInstantiator; 5 | import org.hibernate.metamodel.spi.ValueAccess; 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | 9 | public class AddressInstantiator implements EmbeddableInstantiator { 10 | 11 | Logger log = LogManager.getLogger(this.getClass().getName()); 12 | 13 | public boolean isInstance(Object object, SessionFactoryImplementor sessionFactory) { 14 | return object instanceof Address; 15 | } 16 | 17 | public boolean isSameClass(Object object, SessionFactoryImplementor sessionFactory) { 18 | return object.getClass().equals( Address.class ); 19 | } 20 | 21 | public Object instantiate(ValueAccess valuesAccess, SessionFactoryImplementor sessionFactory) { 22 | // valuesAccess contains attribute values in alphabetical order 23 | final String city = valuesAccess.getValue(0, String.class); 24 | final String postalCode = valuesAccess.getValue(1, String.class); 25 | final String street = valuesAccess.getValue(2, String.class); 26 | log.info("Instantiate Address embeddable for "+street+" "+postalCode+" "+city); 27 | return new Address( street, city, postalCode ); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /08-EmbeddableRecord/src/main/java/com/thorben/janssen/talk/model/Author.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import org.hibernate.annotations.EmbeddableInstantiator; 4 | 5 | import jakarta.persistence.Embedded; 6 | import jakarta.persistence.EmbeddedId; 7 | import jakarta.persistence.Entity; 8 | import jakarta.persistence.Version; 9 | 10 | @Entity 11 | public class Author { 12 | 13 | @EmbeddedId 14 | private AuthorId id; 15 | 16 | @Version 17 | private int version; 18 | 19 | private String firstName; 20 | 21 | private String lastName; 22 | 23 | @Embedded 24 | private Address address; 25 | 26 | public AuthorId getId() { 27 | return id; 28 | } 29 | 30 | public void setId(AuthorId id) { 31 | this.id = id; 32 | } 33 | 34 | public int getVersion() { 35 | return this.version; 36 | } 37 | 38 | public String getFirstName() { 39 | return firstName; 40 | } 41 | 42 | public void setFirstName(String firstName) { 43 | this.firstName = firstName; 44 | } 45 | 46 | public String getLastName() { 47 | return lastName; 48 | } 49 | 50 | public void setLastName(String lastName) { 51 | this.lastName = lastName; 52 | } 53 | 54 | public Address getAddress() { 55 | return address; 56 | } 57 | 58 | public void setAddress(Address address) { 59 | this.address = address; 60 | } 61 | 62 | @Override 63 | public String toString() { 64 | return "Author [id=" + id + ", version=" + version + ", firstName=" + firstName + ", lastName=" + lastName 65 | + ", address=" + address + "]"; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /08-EmbeddableRecord/src/main/java/com/thorben/janssen/talk/model/AuthorId.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import jakarta.persistence.Embeddable; 4 | 5 | @Embeddable 6 | public record AuthorId(String id) { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /08-EmbeddableRecord/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Hibernate Tips 7 | org.hibernate.jpa.HibernatePersistenceProvider 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /08-EmbeddableRecord/src/test/java/com/thorben/janssen/talk/TestPrimaryKeyRecord.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | import com.thorben.janssen.talk.model.Address; 10 | import com.thorben.janssen.talk.model.Author; 11 | import com.thorben.janssen.talk.model.AuthorId; 12 | 13 | import jakarta.persistence.EntityManager; 14 | import jakarta.persistence.EntityManagerFactory; 15 | import jakarta.persistence.Persistence; 16 | 17 | public class TestPrimaryKeyRecord { 18 | 19 | Logger log = LogManager.getLogger(this.getClass().getName()); 20 | 21 | private EntityManagerFactory emf; 22 | 23 | @Before 24 | public void init() { 25 | emf = Persistence.createEntityManagerFactory("my-persistence-unit"); 26 | } 27 | 28 | @After 29 | public void close() { 30 | emf.close(); 31 | } 32 | 33 | @Test 34 | public void testPrimaryKeyRecord() { 35 | log.info("... testPrimaryKeyRecord ..."); 36 | 37 | EntityManager em = emf.createEntityManager(); 38 | em.getTransaction().begin(); 39 | 40 | Author a = new Author(); 41 | a.setId(new AuthorId("Author-42")); 42 | a.setFirstName("Thorben"); 43 | a.setLastName("Janssen"); 44 | a.setAddress(new Address("Dorfstrasse 13", "MainTown", "12345")); 45 | 46 | log.info("Persist new Author entity."); 47 | em.persist(a); 48 | 49 | em.getTransaction().commit(); 50 | em.close(); 51 | 52 | em = emf.createEntityManager(); 53 | em.getTransaction().begin(); 54 | 55 | a = em.find(Author.class, a.getId()); 56 | log.info(a); 57 | 58 | em.getTransaction().commit(); 59 | em.close(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /08-EmbeddableRecord/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /09-SimplifiedJsonMapping/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /09-SimplifiedJsonMapping/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | jar 7 | 8 | 9 | org.hibernate.orm 10 | hibernate-core 11 | 12 | 13 | junit 14 | junit 15 | test 16 | 17 | 18 | org.postgresql 19 | postgresql 20 | test 21 | 22 | 23 | org.apache.logging.log4j 24 | log4j-api 25 | 26 | 27 | org.apache.logging.log4j 28 | log4j-core 29 | test 30 | 31 | 32 | jakarta.xml.bind 33 | jakarta.xml.bind-api 34 | 35 | 36 | 09-SimplifiedJsonMapping 37 | 38 | com.thorben.janssen.talks 39 | HibernateTips 40 | 1.0.0-SNAPSHOT 41 | .. 42 | 43 | -------------------------------------------------------------------------------- /09-SimplifiedJsonMapping/src/main/java/com/thorben/janssen/talk/model/Address.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import org.hibernate.annotations.EmbeddableInstantiator; 4 | 5 | import jakarta.persistence.Embeddable; 6 | 7 | @Embeddable 8 | @EmbeddableInstantiator(AddressInstantiator.class) 9 | public record Address (String street, String city, String postalCode) {} -------------------------------------------------------------------------------- /09-SimplifiedJsonMapping/src/main/java/com/thorben/janssen/talk/model/AddressInstantiator.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import org.hibernate.engine.spi.SessionFactoryImplementor; 4 | import org.hibernate.metamodel.spi.EmbeddableInstantiator; 5 | import org.hibernate.metamodel.spi.ValueAccess; 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | 9 | public class AddressInstantiator implements EmbeddableInstantiator { 10 | 11 | Logger log = LogManager.getLogger(this.getClass().getName()); 12 | 13 | public boolean isInstance(Object object, SessionFactoryImplementor sessionFactory) { 14 | return object instanceof Address; 15 | } 16 | 17 | public boolean isSameClass(Object object, SessionFactoryImplementor sessionFactory) { 18 | return object.getClass().equals( Address.class ); 19 | } 20 | 21 | public Object instantiate(ValueAccess valuesAccess, SessionFactoryImplementor sessionFactory) { 22 | // valuesAccess contains attribute values in alphabetical order 23 | final String city = valuesAccess.getValue(0, String.class); 24 | final String postalCode = valuesAccess.getValue(1, String.class); 25 | final String street = valuesAccess.getValue(2, String.class); 26 | log.info("Instantiate Address embeddable for "+street+" "+postalCode+" "+city); 27 | return new Address( street, city, postalCode ); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /09-SimplifiedJsonMapping/src/main/java/com/thorben/janssen/talk/model/Author.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import org.hibernate.annotations.JdbcTypeCode; 4 | import org.hibernate.type.SqlTypes; 5 | 6 | import jakarta.persistence.Embedded; 7 | import jakarta.persistence.Entity; 8 | import jakarta.persistence.GeneratedValue; 9 | import jakarta.persistence.GenerationType; 10 | import jakarta.persistence.Id; 11 | import jakarta.persistence.Version; 12 | 13 | @Entity 14 | public class Author { 15 | 16 | @Id 17 | @GeneratedValue(strategy = GenerationType.SEQUENCE) 18 | private Long id; 19 | 20 | @Version 21 | private int version; 22 | 23 | private String firstName; 24 | 25 | private String lastName; 26 | 27 | @Embedded 28 | @JdbcTypeCode(SqlTypes.JSON) 29 | private Address address; 30 | 31 | public Long getId() { 32 | return id; 33 | } 34 | 35 | public void setId(Long id) { 36 | this.id = id; 37 | } 38 | 39 | public int getVersion() { 40 | return this.version; 41 | } 42 | 43 | public String getFirstName() { 44 | return firstName; 45 | } 46 | 47 | public void setFirstName(String firstName) { 48 | this.firstName = firstName; 49 | } 50 | 51 | public String getLastName() { 52 | return lastName; 53 | } 54 | 55 | public void setLastName(String lastName) { 56 | this.lastName = lastName; 57 | } 58 | 59 | public Address getAddress() { 60 | return address; 61 | } 62 | 63 | public void setAddress(Address address) { 64 | this.address = address; 65 | } 66 | 67 | @Override 68 | public String toString() { 69 | return "Author [id=" + id + ", version=" + version + ", firstName=" + firstName + ", lastName=" + lastName 70 | + ", address=" + address + "]"; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /09-SimplifiedJsonMapping/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Hibernate Tips 7 | org.hibernate.jpa.HibernatePersistenceProvider 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /09-SimplifiedJsonMapping/src/test/java/com/thorben/janssen/talk/TestJsonSupport.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | import com.thorben.janssen.talk.model.Address; 10 | import com.thorben.janssen.talk.model.Author; 11 | 12 | import jakarta.persistence.EntityManager; 13 | import jakarta.persistence.EntityManagerFactory; 14 | import jakarta.persistence.Persistence; 15 | 16 | public class TestJsonSupport { 17 | 18 | Logger log = LogManager.getLogger(this.getClass().getName()); 19 | 20 | private EntityManagerFactory emf; 21 | 22 | @Before 23 | public void init() { 24 | emf = Persistence.createEntityManagerFactory("my-persistence-unit"); 25 | } 26 | 27 | @After 28 | public void close() { 29 | emf.close(); 30 | } 31 | 32 | @Test 33 | public void testJsonSupport() { 34 | log.info("... testJsonSupport ..."); 35 | 36 | EntityManager em = emf.createEntityManager(); 37 | em.getTransaction().begin(); 38 | 39 | Author a = new Author(); 40 | a.setFirstName("Thorben"); 41 | a.setLastName("Janssen"); 42 | a.setAddress(new Address("Dorfstrasse 13", "MainTown", "12345")); 43 | 44 | log.info("Persist new Author entity."); 45 | em.persist(a); 46 | 47 | em.getTransaction().commit(); 48 | em.close(); 49 | 50 | em = emf.createEntityManager(); 51 | em.getTransaction().begin(); 52 | 53 | a = em.createQuery("SELECT a FROM Author a WHERE a.address.street=:street", Author.class) 54 | .setParameter("street", "Dorfstrasse 13") 55 | .getSingleResult(); 56 | log.info(a); 57 | 58 | em.getTransaction().commit(); 59 | em.close(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /09-SimplifiedJsonMapping/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /10-MultiTenancy/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /.settings/ 3 | .project 4 | -------------------------------------------------------------------------------- /10-MultiTenancy/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | jar 6 | 10-MultiTenancy 7 | 8 | com.thorben.janssen.talks 9 | HibernateTips 10 | 1.0.0-SNAPSHOT 11 | .. 12 | 13 | 14 | 15 | 16 | org.hibernate.orm 17 | hibernate-core 18 | 19 | 20 | junit 21 | junit 22 | test 23 | 24 | 25 | org.postgresql 26 | postgresql 27 | test 28 | 29 | 30 | org.apache.logging.log4j 31 | log4j-api 32 | 33 | 34 | org.apache.logging.log4j 35 | log4j-core 36 | test 37 | 38 | 39 | -------------------------------------------------------------------------------- /10-MultiTenancy/src/main/java/com/thorben/janssen/talk/model/Book.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.time.LocalDate; 4 | 5 | import org.hibernate.annotations.TenantId; 6 | 7 | import jakarta.persistence.Entity; 8 | import jakarta.persistence.GeneratedValue; 9 | import jakarta.persistence.GenerationType; 10 | import jakarta.persistence.Id; 11 | import jakarta.persistence.Version; 12 | 13 | @Entity 14 | public class Book { 15 | 16 | @Id 17 | @GeneratedValue(strategy = GenerationType.SEQUENCE) 18 | private Long id; 19 | 20 | @Version 21 | private int version; 22 | 23 | private String title; 24 | 25 | private LocalDate publishingDate; 26 | 27 | @TenantId 28 | private String tenant; 29 | 30 | public Long getId() { 31 | return this.id; 32 | } 33 | 34 | public void setId(final Long id) { 35 | this.id = id; 36 | } 37 | 38 | public int getVersion() { 39 | return this.version; 40 | } 41 | 42 | public void setVersion(final int version) { 43 | this.version = version; 44 | } 45 | 46 | public String getTitle() { 47 | return title; 48 | } 49 | 50 | public void setTitle(String title) { 51 | this.title = title; 52 | } 53 | 54 | public LocalDate getPublishingDate() { 55 | return this.publishingDate; 56 | } 57 | 58 | public void setPublishingDate(LocalDate publishingDate) { 59 | this.publishingDate = publishingDate; 60 | } 61 | 62 | public String getTenant() { 63 | return tenant; 64 | } 65 | 66 | @Override 67 | public String toString() { 68 | return "Book [id=" + id + ", version=" + version + ", title=" + title + ", publishingDate=" + publishingDate 69 | + ", tenant=" + tenant + "]"; 70 | } 71 | } -------------------------------------------------------------------------------- /10-MultiTenancy/src/main/java/com/thorben/janssen/talk/multitenancy/MultiTenantConnectionProvider.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.multitenancy; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.Properties; 6 | 7 | import org.hibernate.cfg.Environment; 8 | import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl; 9 | import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider; 10 | import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; 11 | 12 | public class MultiTenantConnectionProvider extends 13 | AbstractMultiTenantConnectionProvider { 14 | 15 | private static final long serialVersionUID = 1L; 16 | 17 | private Map conProvMap = new HashMap(); 18 | 19 | public MultiTenantConnectionProvider() { 20 | conProvMap = new HashMap(); 21 | 22 | Properties props = Environment.getProperties(); 23 | String baseUrl = props.getProperty(Environment.URL); 24 | 25 | conProvMap.put("tenant1", createConnectionProvider("tenant1", props, baseUrl)); 26 | conProvMap.put("tenant2", createConnectionProvider("tenant2", props, baseUrl)); 27 | } 28 | 29 | private ConnectionProvider createConnectionProvider(String tenantId, Properties props, String baseUrl) { 30 | props.put( Environment.URL, baseUrl.concat(tenantId)); 31 | 32 | DriverManagerConnectionProviderImpl conProv = new DriverManagerConnectionProviderImpl(); 33 | conProv.configure((Map)props); 34 | return conProv; 35 | } 36 | 37 | @Override 38 | protected ConnectionProvider getAnyConnectionProvider() { 39 | return conProvMap.values().iterator().next(); 40 | } 41 | 42 | @Override 43 | protected ConnectionProvider selectConnectionProvider( 44 | String tenantIdentifier) { 45 | return conProvMap.get(tenantIdentifier); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /10-MultiTenancy/src/main/java/com/thorben/janssen/talk/multitenancy/TenantIdResolver.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.multitenancy; 2 | 3 | import org.hibernate.context.spi.CurrentTenantIdentifierResolver; 4 | 5 | public class TenantIdResolver implements CurrentTenantIdentifierResolver { 6 | 7 | private String tenantIdentifier; 8 | 9 | @Override 10 | public String resolveCurrentTenantIdentifier() { 11 | return tenantIdentifier; 12 | } 13 | 14 | @Override 15 | public boolean validateExistingCurrentSessions() { 16 | return false; 17 | } 18 | 19 | public void setTenantIdentifier(String tenantIdentifier) { 20 | this.tenantIdentifier = tenantIdentifier; 21 | } 22 | } -------------------------------------------------------------------------------- /10-MultiTenancy/src/test/java/com/thorben/janssen/talk/model/TestMultiTenancy.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.logging.log4j.LogManager; 6 | import org.apache.logging.log4j.Logger; 7 | import org.hibernate.Session; 8 | import org.hibernate.SessionFactory; 9 | import org.hibernate.Transaction; 10 | import org.hibernate.boot.Metadata; 11 | import org.hibernate.boot.MetadataSources; 12 | import org.hibernate.boot.registry.StandardServiceRegistryBuilder; 13 | import org.hibernate.engine.spi.SessionFactoryImplementor; 14 | import org.hibernate.service.ServiceRegistry; 15 | import org.junit.After; 16 | import org.junit.Before; 17 | import org.junit.Test; 18 | 19 | import com.thorben.janssen.talk.multitenancy.TenantIdResolver; 20 | 21 | public class TestMultiTenancy { 22 | 23 | Logger log = LogManager.getLogger(this.getClass().getName()); 24 | 25 | private SessionFactory sessionFactory; 26 | 27 | @Before 28 | public void init() { 29 | ServiceRegistry standardRegistry 30 | = new StandardServiceRegistryBuilder().build(); 31 | MetadataSources sources = new MetadataSources(standardRegistry).addAnnotatedClass(Book.class); 32 | Metadata metadata = sources.buildMetadata(); 33 | sessionFactory = metadata.buildSessionFactory(); 34 | } 35 | 36 | @After 37 | public void close() { 38 | sessionFactory.close(); 39 | } 40 | 41 | @Test 42 | public void testMultiTenancy() { 43 | log.info("... testMultiTenancy ..."); 44 | 45 | // Tenant 1 46 | ((TenantIdResolver) ((SessionFactoryImplementor) sessionFactory).getCurrentTenantIdentifierResolver()).setTenantIdentifier("tenant1"); 47 | Session session1 = sessionFactory.openSession(); 48 | Transaction tx1 = session1.getTransaction(); 49 | tx1.begin(); 50 | 51 | Book b1 = new Book(); 52 | b1.setTitle("Book of tenant 1"); 53 | session1.persist(b1); 54 | 55 | tx1.commit(); 56 | session1.close(); 57 | 58 | // Tenant 2 59 | ((TenantIdResolver) ((SessionFactoryImplementor) sessionFactory).getCurrentTenantIdentifierResolver()).setTenantIdentifier("tenant2"); 60 | Session session2 = sessionFactory.openSession(); 61 | Transaction tx2 = session2.getTransaction(); 62 | tx2.begin(); 63 | 64 | Book b2 = new Book(); 65 | b2.setTitle("Book of tenant 2"); 66 | session2.persist(b2); 67 | 68 | tx2.commit(); 69 | session2.close(); 70 | 71 | // Tenant 1 72 | ((TenantIdResolver) ((SessionFactoryImplementor) sessionFactory).getCurrentTenantIdentifierResolver()).setTenantIdentifier("tenant1"); 73 | session1 = sessionFactory.openSession(); 74 | tx1 = session1.getTransaction(); 75 | tx1.begin(); 76 | 77 | List books = session1.createQuery("SELECT b FROM Book b", Book.class).getResultList(); 78 | books.forEach(b -> log.info(b)); 79 | 80 | tx1.commit(); 81 | session1.close(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /10-MultiTenancy/src/test/resources/create-database.sql: -------------------------------------------------------------------------------- 1 | CREATE SCHEMA tenant1; 2 | CREATE TABLE tenant1.book(id bigint NOT NULL, bookdescription jsonb, publishingdate date, title character varying(255), version integer, CONSTRAINT book_pkey PRIMARY KEY (id)); 3 | 4 | CREATE SCHEMA tenant2; 5 | CREATE TABLE tenant2.book(id bigint NOT NULL, bookdescription jsonb, publishingdate date, title character varying(255), version integer, CONSTRAINT book_pkey PRIMARY KEY (id)); 6 | 7 | CREATE SEQUENCE tenant1.book_seq INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1; 8 | CREATE SEQUENCE tenant2.book_seq INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1; -------------------------------------------------------------------------------- /10-MultiTenancy/src/test/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO publisher (id, name, version) VALUES (1, 'Addison Wesley', 0); 2 | INSERT INTO publisher (id, name, version) VALUES (2, 'Manning Publications', 0); 3 | INSERT INTO publisher (id, name, version) VALUES (3, 'OReilly Media', 0); 4 | 5 | INSERT INTO author (id, firstname, lastname, version) VALUES (1, 'Joshua', 'Bloch', 0); 6 | INSERT INTO author (id, firstname, lastname, version) VALUES (2, 'Gavin', 'King', 0); 7 | INSERT INTO author (id, firstname, lastname, version) VALUES (3, 'Christian', 'Bauer', 0); 8 | INSERT INTO author (id, firstname, lastname, version) VALUES (4, 'Gary', 'Gregory', 0); 9 | INSERT INTO author (id, firstname, lastname, version) VALUES (5, 'Raoul-Gabriel', 'Urma', 0); 10 | INSERT INTO author (id, firstname, lastname, version) VALUES (6, 'Mario', 'Fusco', 0); 11 | INSERT INTO author (id, firstname, lastname, version) VALUES (7, 'Alan', 'Mycroft', 0); 12 | INSERT INTO author (id, firstname, lastname, version) VALUES (8, 'Andrew Lee', 'Rubinger', 0); 13 | INSERT INTO author (id, firstname, lastname, version) VALUES (9, 'Aslak', 'Knutsen', 0); 14 | INSERT INTO author (id, firstname, lastname, version) VALUES (10, 'Bill', 'Burke', 0); 15 | INSERT INTO author (id, firstname, lastname, version) VALUES (11, 'Scott', 'Oaks', 0); 16 | 17 | INSERT INTO book (id, publishingdate, title, publisherid, version) VALUES (1, '2008-05-08', 'Effective Java', 1, 0); 18 | INSERT INTO book (id, publishingdate, title, publisherid, version) VALUES (2, '2015-10-01', 'Java Persistence with Hibernate', 2, 0); 19 | INSERT INTO book (id, publishingdate, title, publisherid, version) VALUES (3, '2014-08-28', 'Java 8 in Action', 1, 0); 20 | INSERT INTO book (id, publishingdate, title, publisherid, version) VALUES (4, '2014-03-12', 'Continuous Enterprise Development in Java', 3, 0); 21 | INSERT INTO book (id, publishingdate, title, publisherid, version) VALUES (5, '2010-09-08', 'Enterprise JavaBeans 3.1', 3, 0); 22 | INSERT INTO book (id, publishingdate, title, publisherid, version) VALUES (6, '2014-04-29', 'Java Performance The Definitive Guide', 3, 0); 23 | 24 | INSERT INTO bookauthor (bookid, authorid) VALUES (1, 1); 25 | INSERT INTO bookauthor (bookid, authorid) VALUES (2, 2); 26 | INSERT INTO bookauthor (bookid, authorid) VALUES (2, 3); 27 | INSERT INTO bookauthor (bookid, authorid) VALUES (2, 4); 28 | INSERT INTO bookauthor (bookid, authorid) VALUES (3, 5); 29 | INSERT INTO bookauthor (bookid, authorid) VALUES (3, 6); 30 | INSERT INTO bookauthor (bookid, authorid) VALUES (3, 7); 31 | INSERT INTO bookauthor (bookid, authorid) VALUES (4, 8); 32 | INSERT INTO bookauthor (bookid, authorid) VALUES (4, 9); 33 | INSERT INTO bookauthor (bookid, authorid) VALUES (5, 8); 34 | INSERT INTO bookauthor (bookid, authorid) VALUES (5, 10); 35 | INSERT INTO bookauthor (bookid, authorid) VALUES (6, 11); 36 | 37 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (1, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 1, 0, 1); 38 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (2, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 4, 0, 1); 39 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (3, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 0, 0, 1); 40 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (4, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 4, 0, 1); 41 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (5, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 1, 0, 2); 42 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (6, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 4, 0, 2); 43 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (7, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 3, 0, 2); 44 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (8, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 4, 0, 2); 45 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (9, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 4, 0, 3); 46 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (10, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 3, 0, 3); 47 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (11, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 3, 0, 3); 48 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (12, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 4, 0, 4); 49 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (13, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 4, 0, 4); 50 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (14, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 0, 0, 4); 51 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (15, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 1, 0, 4); 52 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (16, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 4, 0, 5); 53 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (17, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 3, 0, 5); 54 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (18, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 2, 0, 5); 55 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (19, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 1, 0, 5); 56 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (20, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 2, 0, 6); 57 | INSERT INTO review (id, comment, rating, version, book_id) VALUES (21, 'comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment comment', 4, 0, 6); 58 | -------------------------------------------------------------------------------- /10-MultiTenancy/src/test/resources/drop-database.sql: -------------------------------------------------------------------------------- 1 | DROP SCHEMA tenant1 CASCADE; 2 | DROP SCHEMA tenant2 CASCADE; -------------------------------------------------------------------------------- /10-MultiTenancy/src/test/resources/hibernate.properties: -------------------------------------------------------------------------------- 1 | hibernate.dialect org.hibernate.dialect.PostgreSQLDialect 2 | hibernate.connection.driver_class org.postgresql.Driver 3 | hibernate.connection.url jdbc:postgresql://localhost:5432/recipes?currentSchema=multi 4 | # hibernate.connection.url jdbc:postgresql://localhost:5432/recipes?currentSchema= 5 | hibernate.connection.username postgres 6 | hibernate.connection.password postgres 7 | 8 | hibernate.tenant_identifier_resolver com.thorben.janssen.talk.multitenancy.TenantIdResolver 9 | # hibernate.multi_tenant_connection_provider com.thorben.janssen.talk.multitenancy.MultiTenantConnectionProvider -------------------------------------------------------------------------------- /10-MultiTenancy/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /11-Auditing/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /11-Auditing/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 11-Auditing 6 | jar 7 | 8 | com.thorben.janssen.talks 9 | HibernateTips 10 | 1.0.0-SNAPSHOT 11 | .. 12 | 13 | 14 | 15 | 16 | org.hibernate.orm 17 | hibernate-core 18 | 19 | 20 | org.hibernate.orm 21 | hibernate-envers 22 | ${hibernate.version} 23 | 24 | 25 | junit 26 | junit 27 | test 28 | 29 | 30 | org.postgresql 31 | postgresql 32 | test 33 | 34 | 35 | org.apache.logging.log4j 36 | log4j-api 37 | 38 | 39 | org.apache.logging.log4j 40 | log4j-core 41 | test 42 | 43 | 44 | -------------------------------------------------------------------------------- /11-Auditing/src/main/java/com/thorben/janssen/talk/model/Book.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk.model; 2 | 3 | import java.io.Serializable; 4 | import java.time.LocalDate; 5 | import java.util.Optional; 6 | 7 | import jakarta.persistence.Column; 8 | import jakarta.persistence.Entity; 9 | import jakarta.persistence.GeneratedValue; 10 | import jakarta.persistence.GenerationType; 11 | import jakarta.persistence.Id; 12 | import jakarta.persistence.Version; 13 | 14 | import org.hibernate.envers.Audited; 15 | 16 | @Entity 17 | @Audited 18 | public class Book implements Serializable { 19 | 20 | private static final long serialVersionUID = 1L; 21 | 22 | @Id 23 | @GeneratedValue(strategy = GenerationType.AUTO) 24 | @Column(name = "id", updatable = false, nullable = false) 25 | private Long id; 26 | 27 | @Version 28 | @Column(name = "version") 29 | private int version; 30 | 31 | @Column 32 | private String title; 33 | 34 | @Column 35 | private LocalDate publishingDate; 36 | 37 | public Long getId() { 38 | return this.id; 39 | } 40 | 41 | public void setId(final Long id) { 42 | this.id = id; 43 | } 44 | 45 | public int getVersion() { 46 | return this.version; 47 | } 48 | 49 | public void setVersion(final int version) { 50 | this.version = version; 51 | } 52 | 53 | @Override 54 | public boolean equals(Object obj) { 55 | if (this == obj) { 56 | return true; 57 | } 58 | if (!(obj instanceof Book)) { 59 | return false; 60 | } 61 | Book other = (Book) obj; 62 | if (id != null) { 63 | if (!id.equals(other.id)) { 64 | return false; 65 | } 66 | } 67 | return true; 68 | } 69 | 70 | @Override 71 | public int hashCode() { 72 | final int prime = 31; 73 | int result = 1; 74 | result = prime * result + ((id == null) ? 0 : id.hashCode()); 75 | return result; 76 | } 77 | 78 | public String getTitle() { 79 | return title; 80 | } 81 | 82 | public void setTitle(String title) { 83 | this.title = title; 84 | } 85 | 86 | public Optional getPublishingDate() { 87 | return Optional.ofNullable(this.publishingDate); 88 | } 89 | 90 | public void setPublishingDate(LocalDate publishingDate) { 91 | this.publishingDate = publishingDate; 92 | } 93 | 94 | @Override 95 | public String toString() { 96 | String result = getClass().getSimpleName() + " "; 97 | if (title != null && !title.trim().isEmpty()) { 98 | result += "title: " + title; 99 | } 100 | return result; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /11-Auditing/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Thougths on Java 5 | org.hibernate.jpa.HibernatePersistenceProvider 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /11-Auditing/src/test/java/com/thorben/janssen/talk/TestEnvers.java: -------------------------------------------------------------------------------- 1 | package com.thorben.janssen.talk; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | import com.thorben.janssen.talk.model.Book; 10 | 11 | import jakarta.persistence.EntityManager; 12 | import jakarta.persistence.EntityManagerFactory; 13 | import jakarta.persistence.Persistence; 14 | 15 | public class TestEnvers { 16 | 17 | Logger log = LogManager.getLogger(this.getClass().getName()); 18 | 19 | private EntityManagerFactory emf; 20 | 21 | @Before 22 | public void init() { 23 | emf = Persistence.createEntityManagerFactory("my-persistence-unit"); 24 | } 25 | 26 | @After 27 | public void close() { 28 | emf.close(); 29 | } 30 | 31 | @Test 32 | public void testUpdate() { 33 | log.info("... testUpdate ..."); 34 | 35 | EntityManager em = emf.createEntityManager(); 36 | em.getTransaction().begin(); 37 | 38 | Book b = new Book(); 39 | b.setTitle("Hibernate Tips"); 40 | em.persist(b); 41 | 42 | em.getTransaction().commit(); 43 | em.close(); 44 | em = emf.createEntityManager(); 45 | em.getTransaction().begin(); 46 | 47 | b = em.find(Book.class, b.getId()); 48 | b.setTitle("Hibernate Tips - More than 70 solutions for common Hibernate problems"); 49 | 50 | em.getTransaction().commit(); 51 | em.close(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /11-Auditing/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 2 | log4j.appender.stdout.Target=System.out 3 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 4 | log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n 5 | 6 | log4j.rootLogger=info, stdout 7 | log4j.logger.org.hibernate=info 8 | log4j.logger.org.hibernate.stat=debug 9 | log4j.logger.org.hibernate.SQL=debug -------------------------------------------------------------------------------- /11-Auditing/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | 3 | services: 4 | postgres-hibtips: 5 | container_name: postgres-hibtips 6 | build: ./postgres/ 7 | ports: 8 | - 5432:5432 9 | environment: 10 | - POSTGRES_USER=postgres 11 | - POSTGRES_PASSWORD=postgres 12 | 13 | pgadmin-hibtips: 14 | container_name: pgadmin-hibtips 15 | build: ./pgadmin/ 16 | ports: 17 | - 80:80 18 | environment: 19 | PGADMIN_DEFAULT_EMAIL: test@postgresql.org 20 | PGADMIN_DEFAULT_PASSWORD: postgres 21 | links: 22 | - postgres-hibtips 23 | logging: 24 | driver: "none" -------------------------------------------------------------------------------- /docker/pgadmin/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM dpage/pgadmin4:6.2 2 | 3 | COPY /servers.json /pgadmin4/servers.json -------------------------------------------------------------------------------- /docker/pgadmin/servers.json: -------------------------------------------------------------------------------- 1 | { 2 | "Servers": { 3 | "1": { 4 | "Name": "postgres-hibtips", 5 | "Group": "Servers", 6 | "Port": 5432, 7 | "Username": "postgres", 8 | "Password": "postgres", 9 | "Host": "postgres-hibtips", 10 | "SSLMode": "prefer", 11 | "MaintenanceDB": "postgres" 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /docker/postgres/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM postgres:14 2 | 3 | COPY ./create-db.sql /docker-entrypoint-initdb.d/ -------------------------------------------------------------------------------- /docker/postgres/create-db.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE "recipes"; 2 | \c recipes 3 | 4 | CREATE SCHEMA multi; 5 | CREATE TABLE multi.book(id bigint NOT NULL, publishingdate date, title character varying(255), tenant character varying(255), version integer, CONSTRAINT book_pkey PRIMARY KEY (id)); 6 | CREATE SEQUENCE multi.Book_SEQ INCREMENT 50 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1; 7 | 8 | CREATE SCHEMA tenant1; 9 | CREATE TABLE tenant1.book(id bigint NOT NULL, publishingdate date, title character varying(255), tenant character varying(255), version integer, CONSTRAINT book_pkey PRIMARY KEY (id)); 10 | CREATE SEQUENCE tenant1.Book_SEQ INCREMENT 50 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1; 11 | 12 | CREATE SCHEMA tenant2; 13 | CREATE TABLE tenant2.book(id bigint NOT NULL, publishingdate date, title character varying(255), tenant character varying(255), version integer, CONSTRAINT book_pkey PRIMARY KEY (id)); 14 | CREATE SEQUENCE tenant2.Book_SEQ INCREMENT 50 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1; -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | com.thorben.janssen.talks 7 | HibernateTips 8 | 1.0.0-SNAPSHOT 9 | pom 10 | 11 | 17 12 | 17 13 | UTF-8 14 | 5.6.15.Final 15 | 6.3.0.Final 16 | 17 | 18 | 19 | 20 | 21 | org.hibernate.orm 22 | hibernate-core 23 | ${hibernate.version} 24 | 25 | 26 | org.hibernate 27 | hibernate-core-jakarta 28 | ${hibernate5.version} 29 | 30 | 31 | junit 32 | junit 33 | 4.13.1 34 | test 35 | 36 | 37 | org.postgresql 38 | postgresql 39 | 42.7.2 40 | test 41 | 42 | 43 | org.apache.logging.log4j 44 | log4j-api 45 | 2.17.1 46 | 47 | 48 | org.apache.logging.log4j 49 | log4j-core 50 | 2.17.1 51 | test 52 | 53 | 54 | jakarta.xml.bind 55 | jakarta.xml.bind-api 56 | 3.0.1 57 | 58 | 59 | 60 | 61 | 62 | 63 | org.codehaus.mojo 64 | build-helper-maven-plugin 65 | 3.0.0 66 | 67 | 68 | add-source 69 | generate-sources 70 | 71 | add-source 72 | 73 | 74 | 75 | target/generated-sources/annotations 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 01-LogQueryExecutionTime 85 | 02-JoinUnassociatedEntities 86 | 03-DatabaseViews 87 | 04-OrderAssociation 88 | 05-KeepAssociationOrder 89 | 06-PrimaryKeyUuid 90 | 07-MapOptionalAssociations 91 | 08-EmbeddableRecord 92 | 09-SimplifiedJsonMapping 93 | 10-MultiTenancy 94 | 11-Auditing 95 | 96 | --------------------------------------------------------------------------------