diff --git a/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc b/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc index cfdce59559..621ff60717 100644 --- a/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc +++ b/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc @@ -741,8 +741,6 @@ See the <> annotation as well. ==== -//TODO: Add example - [[annotations-hibernate-entity]] ==== [line-through]#`@Entity`# @@ -933,7 +931,7 @@ The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibern By default, `List` indexes are stored starting at zero. Generally used in conjunction with <>. -//TODO: Add example +See the <> section for more info. [[annotations-hibernate-loader]] ==== `@Loader` diff --git a/documentation/src/main/asciidoc/userguide/chapters/domain/collections.adoc b/documentation/src/main/asciidoc/userguide/chapters/domain/collections.adoc index 0bde60d9d7..584b03e980 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/domain/collections.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/domain/collections.adoc @@ -380,6 +380,36 @@ include::{extrasdir}/collections-bidirectional-ordered-list-order-column-example When fetching the collection, Hibernate will use the fetched ordered columns to sort the elements according to the `@OrderColumn` mapping. +[[collections-customizing-ordered-list-ordinal]] +===== Customizing ordered list ordinal + +You can customize the ordinal of the underlying ordered list by using the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/ListIndexBase.html[`@ListIndexBase`] annotation. + +[[collections-customizing-ordered-list-ordinal-mapping-example]] +.`@ListIndexBase` mapping example +==== +[source,java] +---- +include::{sourcedir}/OrderColumnListIndexBaseTest.java[tags=collections-customizing-ordered-list-ordinal-mapping-example,indent=0] +---- +==== + +When inserting two `Phone` records, Hibernate is going to start the List index from 100 this time. + +[[collections-customizing-ordered-list-ordinal-persist-example]] +.`@ListIndexBase` persist example +==== +[source,java] +---- +include::{sourcedir}/OrderColumnListIndexBaseTest.java[tags=collections-customizing-ordered-list-ordinal-persist-example,indent=0] +---- + +[source,sql] +---- +include::{extrasdir}/collections-customizing-ordered-list-ordinal-persist-example.sql[] +---- +==== + [[collections-set]] ==== Sets diff --git a/documentation/src/main/asciidoc/userguide/chapters/domain/extras/collections/collections-customizing-ordered-list-ordinal-persist-example.sql b/documentation/src/main/asciidoc/userguide/chapters/domain/extras/collections/collections-customizing-ordered-list-ordinal-persist-example.sql new file mode 100644 index 0000000000..28750928f3 --- /dev/null +++ b/documentation/src/main/asciidoc/userguide/chapters/domain/extras/collections/collections-customizing-ordered-list-ordinal-persist-example.sql @@ -0,0 +1,13 @@ +INSERT INTO Phone("number", person_id, type, id) +VALUES ('028-234-9876', 1, 'landline', 1) + +INSERT INTO Phone("number", person_id, type, id) +VALUES ('072-122-9876', 1, 'mobile', 2) + +UPDATE Phone +SET order_id = 100 +WHERE id = 1 + +UPDATE Phone +SET order_id = 101 +WHERE id = 2 \ No newline at end of file diff --git a/documentation/src/test/java/org/hibernate/userguide/collections/OrderColumnListIndexBaseTest.java b/documentation/src/test/java/org/hibernate/userguide/collections/OrderColumnListIndexBaseTest.java new file mode 100644 index 0000000000..71db2b6256 --- /dev/null +++ b/documentation/src/test/java/org/hibernate/userguide/collections/OrderColumnListIndexBaseTest.java @@ -0,0 +1,149 @@ +/* + * 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.collections; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OrderColumn; + +import org.hibernate.annotations.ListIndexBase; +import org.hibernate.annotations.NaturalId; +import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; + +import org.junit.Test; + +import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; + +/** + * @author Vlad Mihalcea + */ +public class OrderColumnListIndexBaseTest extends BaseEntityManagerFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + Person.class, + Phone.class, + }; + } + + @Test + public void testLifecycle() { + doInJPA( this::entityManagerFactory, entityManager -> { + //tag::collections-customizing-ordered-list-ordinal-persist-example[] + Person person = new Person( 1L ); + entityManager.persist( person ); + person.addPhone( new Phone( 1L, "landline", "028-234-9876" ) ); + person.addPhone( new Phone( 2L, "mobile", "072-122-9876" ) ); + //end::collections-customizing-ordered-list-ordinal-persist-example[] + } ); + } + + @Entity(name = "Person") + public static class Person { + + @Id + private Long id; + + //tag::collections-customizing-ordered-list-ordinal-mapping-example[] + @OneToMany(mappedBy = "person", cascade = CascadeType.ALL) + @OrderColumn(name = "order_id") + @ListIndexBase(100) + private List phones = new ArrayList<>(); + //end::collections-customizing-ordered-list-ordinal-mapping-example[] + + public Person() { + } + + public Person(Long id) { + this.id = id; + } + + public List getPhones() { + return phones; + } + + public void addPhone(Phone phone) { + phones.add( phone ); + phone.setPerson( this ); + } + + public void removePhone(Phone phone) { + phones.remove( phone ); + phone.setPerson( null ); + } + } + + @Entity(name = "Phone") + public static class Phone { + + @Id + private Long id; + + private String type; + + @Column(name = "`number`", unique = true) + @NaturalId + private String number; + + @ManyToOne + private Person person; + + public Phone() { + } + + public Phone(Long id, String type, String number) { + this.id = id; + this.type = type; + this.number = number; + } + + public Long getId() { + return id; + } + + public String getType() { + return type; + } + + public String getNumber() { + return number; + } + + public Person getPerson() { + return person; + } + + public void setPerson(Person person) { + this.person = person; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + Phone phone = (Phone) o; + return Objects.equals( number, phone.number ); + } + + @Override + public int hashCode() { + return Objects.hash( number ); + } + } +}