From b9189093599c6e599d05eca0f1db34bd2e36af23 Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Wed, 8 Feb 2023 15:00:56 +0100 Subject: [PATCH] HHH-16152 Documentation for @PartitionKey --- .../userguide/appendices/Annotations.adoc | 7 ++ .../chapters/domain/DomainModel.adoc | 1 + .../chapters/domain/partitioning.adoc | 41 +++++++ .../identifier/SimplePartitionKeyTest.java | 104 ++++++++++++++++++ 4 files changed, 153 insertions(+) create mode 100644 documentation/src/main/asciidoc/userguide/chapters/domain/partitioning.adoc create mode 100644 documentation/src/test/java/org/hibernate/userguide/mapping/identifier/SimplePartitionKeyTest.java diff --git a/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc b/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc index 511aebdded..5da843760c 100644 --- a/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc +++ b/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc @@ -1184,6 +1184,13 @@ The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibern See the <> section for more info. +[[annotations-hibernate-partition-key]] +==== `@PartitionKey` + +The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/PartitionKey.html[`@PartitionKey`] annotation is used to identify a field of an entity that holds the partition key of a table. + +See the <> section for more info. + [[annotations-hibernate-persister]] ==== `@Persister` diff --git a/documentation/src/main/asciidoc/userguide/chapters/domain/DomainModel.adoc b/documentation/src/main/asciidoc/userguide/chapters/domain/DomainModel.adoc index f23009dbde..74702582c2 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/domain/DomainModel.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/domain/DomainModel.adoc @@ -32,6 +32,7 @@ include::identifiers.adoc[] include::associations.adoc[] include::collections.adoc[] include::natural_id.adoc[] +include::partitioning.adoc[] include::dynamic_model.adoc[] include::inheritance.adoc[] include::immutability.adoc[] diff --git a/documentation/src/main/asciidoc/userguide/chapters/domain/partitioning.adoc b/documentation/src/main/asciidoc/userguide/chapters/domain/partitioning.adoc new file mode 100644 index 0000000000..d286ef0e59 --- /dev/null +++ b/documentation/src/main/asciidoc/userguide/chapters/domain/partitioning.adoc @@ -0,0 +1,41 @@ +[[partitioning]] +=== Partitioning +:root-project-dir: ../../../../../../.. +:documentation-project-dir: {root-project-dir}/documentation +:example-dir-partition-key: {documentation-project-dir}/src/test/java/org/hibernate/userguide/mapping/identifier +:extrasdir: extras + +In data management, it is sometimes necessary to split data of a table into various (physical) partitions, +based on partition keys and a partitioning scheme. + +Due to the nature of partitioning, it is vital for the database to know the partition key of a row for certain operations, +like SQL update and delete statements. If a database doesn't know the partition of a row that should be updated or deleted, +then it must look for the row in all partitions, leading to poor performance. + +The `@PartitionKey` annotation is a way to tell Hibernate about the column, such that it can include a column restriction as +predicate into SQL update and delete statements for entity state changes. + +[[partition-key-mapping]] +==== Partition Key Mapping + +Partition keys are defined in terms of one or more persistent attributes. + +[[partition-key-simple-basic-attribute-mapping-example]] +.Partition key using single basic attribute +==== +[source,java] +---- +include::{example-dir-partition-key}/SimplePartitionKeyTest.java[tags=partition-key-simple-basic-attribute-mapping-example,indent=0] +---- +==== + +When updating or deleting an entity, Hibernate will include a partition key constraint similar to this + +[[partition-key-simple-basic-attribute-sql-example]] +==== +[source,sql] +---- +update user_tbl set firstname=?,lastname=?,tenantKey=? where id=? and tenantKey=? +delete from user_tbl where id=? and tenantKey=? +---- +==== \ No newline at end of file diff --git a/documentation/src/test/java/org/hibernate/userguide/mapping/identifier/SimplePartitionKeyTest.java b/documentation/src/test/java/org/hibernate/userguide/mapping/identifier/SimplePartitionKeyTest.java new file mode 100644 index 0000000000..6fc6258537 --- /dev/null +++ b/documentation/src/test/java/org/hibernate/userguide/mapping/identifier/SimplePartitionKeyTest.java @@ -0,0 +1,104 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.userguide.mapping.identifier; + +import org.hibernate.annotations.PartitionKey; +import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase; + +import org.junit.Test; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; + +/** + * @author Christian Beikov + */ +public class SimplePartitionKeyTest extends BaseEntityManagerFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + User.class + }; + } + + @Test + public void test() { + doInJPA(this::entityManagerFactory, entityManager -> { + User user = new User(); + user.setId( 1L ); + user.setFirstname( "John" ); + user.setLastname( "Doe" ); + user.setTenantKey( "tenant1" ); + + entityManager.persist( user ); + }); + doInJPA( this::entityManagerFactory, entityManager -> { + User user = entityManager.find( User.class, 1L ); + user.setLastname( "Cash" ); + } ); + doInJPA( this::entityManagerFactory, entityManager -> { + entityManager.remove( entityManager.find( User.class, 1L ) ); + } ); + } + + @Table(name = "user_tbl") + //tag::partition-key-simple-basic-attribute-mapping-example[] + @Entity(name = "User") + public static class User { + + @Id + private Long id; + + private String firstname; + + private String lastname; + + @PartitionKey + private String tenantKey; + + //Getters and setters are omitted for brevity + //end::partition-key-simple-basic-attribute-mapping-example[] + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String title) { + this.firstname = title; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String author) { + this.lastname = author; + } + + public String getTenantKey() { + return tenantKey; + } + + public void setTenantKey(String tenantKey) { + this.tenantKey = tenantKey; + } + //tag::partition-key-simple-basic-attribute-mapping-example[] + } + //end::partition-key-simple-basic-attribute-mapping-example[] +}