Skip to content

Commit 77ea618

Browse files
committed
HHH-11186 - Add examples for all Hibernate annotations
Document @orderby annotation
1 parent 73affab commit 77ea618

File tree

4 files changed

+224
-1
lines changed

4 files changed

+224
-1
lines changed

documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibern
10771077

10781078
It differs from the JPA <<annotations-jpa-orderby>> annotation because the JPA annotation expects a JPQL order-by fragment, not an SQL directive.
10791079

1080-
//TODO: Add example
1080+
See the <<chapters/domain/collections.adoc#collections-customizing-ordered-by-sql-clause, `@OrderBy` mapping>> section for more info.
10811081

10821082
[[annotations-hibernate-paramdef]]
10831083
==== `@ParamDef`

documentation/src/main/asciidoc/userguide/chapters/domain/collections.adoc

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,41 @@ include::{extrasdir}/collections-customizing-ordered-list-ordinal-persist-exampl
410410
----
411411
====
412412

413+
[[collections-customizing-ordered-by-sql-clause]]
414+
===== Customizing ORDER BY SQL clause
415+
416+
While the JPA
417+
http://docs.oracle.com/javaee/7/api/javax/persistence/OrderBy.html[`@OrderBy`] annotation allows you to specify the entity attributes used for sorting
418+
when fetching the current annotated collection, the Hibernate specific
419+
https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/OrderBy.html[`@OrderBy`] annotation is used to specify a *SQL* clause instead.
420+
421+
In the following example, the `@OrderBy` annotations uses the `CHAR_LENGTH` SQL function to order the `Article` entities by the size of their contents.
422+
423+
[[collections-customizing-ordered-by-sql-clause-mapping-example]]
424+
.`@OrderBy` mapping example
425+
====
426+
[source,java]
427+
----
428+
include::{sourcedir}/OrderedBySQLTest.java[tags=collections-customizing-ordered-by-sql-clause-mapping-example,indent=0]
429+
----
430+
====
431+
432+
When fetching the `articles` collection, Hibernate uses the ORDER BY SQL clause provided by the mapping:
433+
434+
[[collections-customizing-ordered-by-sql-clause-fetching-example]]
435+
.`@OrderBy` fetching example
436+
====
437+
[source,java]
438+
----
439+
include::{sourcedir}/OrderedBySQLTest.java[tags=collections-customizing-ordered-by-sql-clause-fetching-example,indent=0]
440+
----
441+
442+
[source,sql]
443+
----
444+
include::{extrasdir}/collections-customizing-ordered-by-sql-clause-fetching-example.sql[]
445+
----
446+
====
447+
413448
[[collections-set]]
414449
==== Sets
415450

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
select
2+
a.person_id as person_i4_0_0_,
3+
a.id as id1_0_0_,
4+
a.content as content2_0_1_,
5+
a.name as name3_0_1_,
6+
a.person_id as person_i4_0_1_
7+
from
8+
Article a
9+
where
10+
a.person_id = ?
11+
order by
12+
CHAR_LENGTH(a.name) desc
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.userguide.collections;
8+
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
import javax.persistence.CascadeType;
12+
import javax.persistence.Entity;
13+
import javax.persistence.FetchType;
14+
import javax.persistence.GeneratedValue;
15+
import javax.persistence.Id;
16+
import javax.persistence.ManyToOne;
17+
import javax.persistence.OneToMany;
18+
19+
import org.hibernate.dialect.H2Dialect;
20+
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
21+
22+
import org.hibernate.testing.RequiresDialect;
23+
import org.junit.Test;
24+
25+
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
26+
import static org.junit.Assert.assertEquals;
27+
28+
/**
29+
* @author Vlad Mihalcea
30+
*/
31+
@RequiresDialect(H2Dialect.class)
32+
public class OrderedBySQLTest extends BaseEntityManagerFunctionalTestCase {
33+
34+
@Override
35+
protected Class<?>[] getAnnotatedClasses() {
36+
return new Class<?>[] {
37+
Person.class,
38+
Article.class,
39+
};
40+
}
41+
42+
@Test
43+
public void testLifecycle() {
44+
doInJPA( this::entityManagerFactory, entityManager -> {
45+
Person person = new Person();
46+
person.setId( 1L );
47+
person.setName( "Vlad Mihalcea" );
48+
49+
person.addArticle(
50+
new Article(
51+
"High-Performance JDBC",
52+
"Connection Management, Statement Caching, Batch Updates"
53+
)
54+
);
55+
person.addArticle(
56+
new Article(
57+
"High-Performance Hibernate",
58+
"Associations, Lazy fetching, Concurrency Control, Second-level Caching"
59+
)
60+
);
61+
entityManager.persist( person );
62+
} );
63+
doInJPA( this::entityManagerFactory, entityManager -> {
64+
//tag::collections-customizing-ordered-by-sql-clause-fetching-example[]
65+
Person person = entityManager.find( Person.class, 1L );
66+
assertEquals(
67+
"High-Performance Hibernate",
68+
person.getArticles().get( 0 ).getName()
69+
);
70+
//end::collections-customizing-ordered-by-sql-clause-fetching-example[]
71+
} );
72+
}
73+
74+
//tag::collections-customizing-ordered-by-sql-clause-mapping-example[]
75+
@Entity(name = "Person")
76+
public static class Person {
77+
78+
@Id
79+
private Long id;
80+
81+
private String name;
82+
83+
@OneToMany(mappedBy = "person", cascade = CascadeType.ALL)
84+
@org.hibernate.annotations.OrderBy(clause = "CHAR_LENGTH(name) DESC")
85+
private List<Article> articles = new ArrayList<>();
86+
87+
//Getters and setters are omitted for brevity
88+
//end::collections-customizing-ordered-by-sql-clause-mapping-example[]
89+
90+
public Long getId() {
91+
return id;
92+
}
93+
94+
public void setId(Long id) {
95+
this.id = id;
96+
}
97+
98+
public String getName() {
99+
return name;
100+
}
101+
102+
public void setName(String name) {
103+
this.name = name;
104+
}
105+
106+
public List<Article> getArticles() {
107+
return articles;
108+
}
109+
110+
public void addArticle(Article article) {
111+
article.setPerson( this );
112+
articles.add( article );
113+
}
114+
//tag::collections-customizing-ordered-by-sql-clause-mapping-example[]
115+
}
116+
117+
@Entity(name = "Article")
118+
public static class Article {
119+
120+
@Id
121+
@GeneratedValue
122+
private Long id;
123+
124+
private String name;
125+
126+
private String content;
127+
128+
@ManyToOne(fetch = FetchType.LAZY)
129+
private Person person;
130+
131+
private Article() {
132+
}
133+
134+
public Article(String name, String content) {
135+
this.name = name;
136+
this.content = content;
137+
}
138+
139+
//Getters and setters are omitted for brevity
140+
//end::collections-customizing-ordered-by-sql-clause-mapping-example[]
141+
142+
public Long getId() {
143+
return id;
144+
}
145+
146+
public void setId(Long id) {
147+
this.id = id;
148+
}
149+
150+
public String getName() {
151+
return name;
152+
}
153+
154+
public void setName(String name) {
155+
this.name = name;
156+
}
157+
158+
public String getContent() {
159+
return content;
160+
}
161+
162+
public void setContent(String content) {
163+
this.content = content;
164+
}
165+
166+
public Person getPerson() {
167+
return person;
168+
}
169+
170+
public void setPerson(Person person) {
171+
this.person = person;
172+
}
173+
//tag::collections-customizing-ordered-by-sql-clause-mapping-example[]
174+
}
175+
//end::collections-customizing-ordered-by-sql-clause-mapping-example[]
176+
}

0 commit comments

Comments
 (0)