Skip to content

Commit 1239698

Browse files
committed
HSEARCH-5300 Add documentation for static metamodel
1 parent 5a9be86 commit 1239698

File tree

10 files changed

+1038
-0
lines changed

10 files changed

+1038
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright Red Hat Inc. and Hibernate Authors
3+
[[static-metamodel-overview]]
4+
= Overview of the static metamodel
5+
6+
include::../components/_incubating-warning.adoc[]
7+
8+
The static metamodel class describes the index structure. Each indexed entity (index) is represented by a single class
9+
that may contain inner classes describing the embeddables (i.e. nested/flattened objects). These classes contain <<static-metamodel-processor-field-reference-types,field references>>
10+
representing index fields and their search capabilities.
11+
12+
The name of this root class is constructed from the indexed entity name by adding `pass:[__]` (two underscores) suffix, e.g. `MySearchEntitypass:[__]`.
13+
If the indexed entity is a (static) inner class, then all the owning classes will be part of the name delimited with a `pass:[_]` (single underscore),
14+
e.g. `MyOuterClasspass:[_]MySearchEntitypass:[__]`.
15+
These classes are created in the same package where the search entity they represent is located.
16+
17+
The root metamodel class that describes the indexed entity has a static field `INDEX` that users can use to interact with the metamodel.
18+
It serves two primary purposes:
19+
20+
* It simplifies creating the search scope and building search queries for such scope.
21+
* It provides a way to reference index fields when constructing queries.
22+
23+
NOTE: While the default naming convention was described in this section,
24+
there are plans to provide more flexibility in this area to the users (see https://hibernate.atlassian.net/browse/HSEARCH-5366[HSEARCH-5366]) .
25+
26+
====
27+
[source, JAVA, indent=0, subs="+callouts"]
28+
----
29+
include::{sourcedir}/org/hibernate/search/documentation/search/metamodel/MetamodelIT.java[tags=entryPoint]
30+
----
31+
<1> Obtain the search session.
32+
<2> Create the search scope over the book index. Using such scope in the <<search-dsl,Search DSL>> will automatically
33+
limit acceptable field references to the ones obtained from the `Book__.INDEX`
34+
<3> Use the metamodel to reference the fields when creating the queries.
35+
====
36+
37+
[[static-metamodel-processor-field-reference-types]]
38+
== Field reference types
39+
40+
A field reference type describes the set of search capabilities a particular index field has, in particular,
41+
what kind of projections/aggregations/predicates/sorts are allowed, if any. It does so by implementing a
42+
subset of search traits interfaces defined in `org.hibernate.search.engine.search.reference.pass:[*]`, which in turn allows
43+
performing compile-time checks when building <<search-dsl,search queries>>.
44+
45+
====
46+
[source, JAVA, indent=0, subs="+callouts"]
47+
----
48+
include::{sourcedir}/org/hibernate/search/documentation/search/metamodel/MetamodelIT.java[tags=compileCheck-pass]
49+
----
50+
<1> If the title field is projectable then this compiles works fine,
51+
otherwise compilation fails with an error similar to:
52+
+
53+
----
54+
error: no suitable method found for field(ValueFieldReferenceP0P13P14P2P4P5P6P7P8P9<Book__,String,String,String,String>)
55+
----
56+
+
57+
as such field reference (for a filed with `Projectable.NO`) will not implement the required `FieldProjectionFieldReference` interface.
58+
====
59+
60+
The field reference also provides a way to quickly switch between <<search-dsl-argument-type,different value models>> when necessary.
61+
62+
====
63+
[source, JAVA, indent=0, subs="+callouts"]
64+
----
65+
include::{sourcedir}/org/hibernate/search/documentation/search/metamodel/MetamodelIT.java[tags=valueModel]
66+
----
67+
<1> Calling `string()` on a field reference is an eqivalent to `.field( "genre" ).matching( <search value>, ValueModel.STRING )`
68+
====
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright Red Hat Inc. and Hibernate Authors
3+
[[static-metamodel-processor]]
4+
= Annotation processor
5+
6+
include::../components/_incubating-warning.adoc[]
7+
8+
[[static-metamodel-processor-enabling]]
9+
== Enabling the annotation processor
10+
11+
Hibernate Search provides a dedicated annotation processor to generate the static metamodel classes.
12+
This annotation processor is located in the `org.hibernate.search:hibernate-search-metamodel-processor`.
13+
14+
The annotation processor has to be added to the build, e.g. for Maven:
15+
16+
====
17+
[source,XML,subs="+attributes"]
18+
----
19+
<plugin>
20+
<artifactId>maven-compiler-plugin</artifactId>
21+
<executions>
22+
<execution>
23+
<id>default-compile</id>
24+
<configuration>
25+
<annotationProcessors>
26+
<annotationProcessor>org.hibernate.search.metamodel.processor.HibernateSearchMetamodelProcessor</annotationProcessor> <1>
27+
</annotationProcessors>
28+
<annotationProcessorPaths>
29+
<path>
30+
<groupId>org.hibernate.search</groupId>
31+
<artifactId>hibernate-search-metamodel-processor</artifactId> <2>
32+
</path>
33+
<path>
34+
<groupId>org.hibernate.search</groupId>
35+
<artifactId>hibernate-search-backend-lucene</artifactId> <3>
36+
</path>
37+
</annotationProcessorPaths>
38+
</configuration>
39+
</execution>
40+
</executions>
41+
</plugin>
42+
----
43+
44+
<1> Provide the fully qualified class name of the annotation processor that generates the metamodel.
45+
<2> Add the `org.hibernate.search:hibernate-search-metamodel-processor` dependency as an annotation processor path for the Maven compiler plugin to be able to actually find the processor.
46+
<3> Add the backend dependency, in this example, the <<backend-lucene,Lucene backend>>, as an annotation processor path.
47+
It is important to include the same backend that the application is using to make sure that the generated metamodel classes reflect all the backend specifics.
48+
For example, backends might have different defaults, resulting in a different set of field traits depending on the backend.
49+
50+
NOTE: The version of both annotation processor and backend dependencies are skipped in the definition of the annotation paths, as in case the Hibernate Search BOM is imported via dependency management, the compiler plugin will use the managed versions.
51+
This way the generated metamodel classes will be based on the same backend that the application uses.
52+
====
53+
54+
[[static-metamodel-processor-configuration]]
55+
== Configuration
56+
57+
The annotation processor options are passed as the compiler arguments with the `-A` key:
58+
59+
====
60+
[source,XML,subs="+attributes"]
61+
----
62+
<plugin>
63+
<artifactId>maven-compiler-plugin</artifactId>
64+
<executions>
65+
<execution>
66+
<id>default-compile</id>
67+
<configuration>
68+
<compilerArgs>
69+
<arg>-Aorg.hibernate.search.metamodel.processor.generated_annotation.timestamp=false</arg> <1>
70+
<arg><!-- ... --></arg> <2>
71+
</compilerArgs>
72+
<!-- ... --> <3>
73+
</configuration>
74+
</execution>
75+
</executions>
76+
</plugin>
77+
----
78+
79+
<1> Pass the annotation processor parameters using the `-A` key.
80+
<2> Pass any other compiler arguments required by the build.
81+
<3> Further compiler plugin configuration.
82+
====
83+
84+
The following annotation processor configuration properties are available:
85+
86+
[[static-metamodel-processor-configuration-generated_annotation-add]]`org.hibernate.search.metamodel.processor.generated_annotation.add`::
87+
Description:::
88+
Whether to add the `@Generated` annotation to the generated static metamodel classes.
89+
Default value:::
90+
`true`
91+
92+
[[static-metamodel-processor-configuration-generated_annotation-timestamp]]`org.hibernate.search.metamodel.processor.generated_annotation.timestamp`::
93+
Description:::
94+
Defines whether the `@Generated` annotation includes the `date` attribute.
95+
Having the date attribute will result in non-reproducible builds, as the timestamp will be different for each compilation.
96+
Hence, it is disabled by default.
97+
Default value:::
98+
`false`
99+
100+
[[static-metamodel-processor-configuration-add_generated_annotation]]`org.hibernate.search.metamodel.processor.backend.version`::
101+
Description:::
102+
Explicitly define the backend version. By default, the processor will use the latest compatible version of the backend.
103+
This option can be used if the static metamodel is required for an older backend version.
104+
Default value:::
105+
`<latest>`
106+
107+
[[static-metamodel-processor-limitations]]
108+
== Current annotation processor limitations
109+
110+
While the annotation processor is in its early stages of development, it has a few limitations:
111+
112+
* Any use of <<binding-valuebridge-valuebinder,custom binders>> will be ignored and should produce a compiler warning.
113+
This means that if the search entities rely on custom binders, fields that those binders produce will be missing from the generated metamodel.
114+
* <<mapper-orm-custom-annotations,Custom mapping annotations>> are not supported.
115+
* <<mapping-programmatic,Programmatic mapping>> is also unsupported by the annotation processor.
116+
As the annotation processor cannot easily read programmatic mapping definitions, this limitation is here to stay.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright Red Hat Inc. and Hibernate Authors
3+
[[static-metamodel]]
4+
= Static metamodel
5+
6+
include::../components/_incubating-warning.adoc[]
7+
8+
Hibernate Search static metamodel represents the index structure
9+
that provides a type-safe way of creating search queries through the <<search-dsl,Search DSL>>.
10+
11+
:leveloffset: +1
12+
13+
include::_static-metamodel-overview.adoc[]
14+
15+
include::_static-metamodel-processor.adoc[]
16+
17+
:leveloffset: -1

documentation/src/main/asciidoc/public/reference/index.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ include::_backend-elasticsearch.adoc[]
6363

6464
include::_coordination.adoc[]
6565

66+
include::_static-metamodel.adoc[]
67+
6668
include::_integrations.adoc[]
6769

6870
include::_limitations.adoc[]
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.search.documentation.search.metamodel;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
10+
import jakarta.persistence.Entity;
11+
import jakarta.persistence.Id;
12+
import jakarta.persistence.ManyToMany;
13+
14+
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField;
15+
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed;
16+
17+
@Entity
18+
@Indexed
19+
public class Author {
20+
21+
@Id
22+
private Integer id;
23+
24+
@FullTextField(analyzer = "name")
25+
private String firstName;
26+
27+
@FullTextField(analyzer = "name")
28+
private String lastName;
29+
30+
@ManyToMany(mappedBy = "authors")
31+
private List<Book> books = new ArrayList<>();
32+
33+
public Author() {
34+
}
35+
36+
public Integer getId() {
37+
return id;
38+
}
39+
40+
public void setId(Integer id) {
41+
this.id = id;
42+
}
43+
44+
public String getFirstName() {
45+
return firstName;
46+
}
47+
48+
public void setFirstName(String firstName) {
49+
this.firstName = firstName;
50+
}
51+
52+
public String getLastName() {
53+
return lastName;
54+
}
55+
56+
public void setLastName(String lastName) {
57+
this.lastName = lastName;
58+
}
59+
60+
public List<Book> getBooks() {
61+
return books;
62+
}
63+
64+
public void setBooks(List<Book> books) {
65+
this.books = books;
66+
}
67+
}

0 commit comments

Comments
 (0)