├── .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 |
--------------------------------------------------------------------------------