improve Javadoc of org.hibernate.annotations.processing

This commit is contained in:
Gavin King 2023-07-10 11:52:59 +02:00
parent 605a732e05
commit 99d8bf0832
4 changed files with 159 additions and 8 deletions

View File

@ -57,7 +57,24 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
* @see jakarta.persistence.EntityManager#createQuery(String,Class) * @see jakarta.persistence.EntityManager#createQuery(String,Class)
* @see org.hibernate.Session#createSelectionQuery(String,Class) * @see org.hibernate.Session#createSelectionQuery(String,Class)
* *
* @implNote The static HQL type checker is not aware of metadata defined
* purely in XML, nor of JPA converters, and therefore sometimes
* reports false positives. That is, it rejects queries at compile
* time that would be accepted at runtime.
* <p>
* Therefore, by default, HQL specified in {@code NamedQuery}
* annotations is always validated for both syntax and semantics,
* but only illegal syntax is reported with severity
* {@link javax.tools.Diagnostic.Kind#ERROR}. Problems with the
* semantics of HQL named queries (typing problem) are reported to
* the Java compiler by the Metamodel Generator with severity
* {@link javax.tools.Diagnostic.Kind#WARNING}.
* <p>
* So, actually, the effect of {@code CheckHQL} is only to change
* the severity of reported problem.
*
* @author Gavin King * @author Gavin King
* @since 6.3
*/ */
@Target({PACKAGE, TYPE}) @Target({PACKAGE, TYPE})
@Retention(CLASS) @Retention(CLASS)

View File

@ -16,10 +16,20 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
/** /**
* Identifies a method of an abstract class or interface as defining * Identifies a method of an abstract class or interface as defining
* the signature of a finder method, and being generated automatically * the signature of a <em>finder method</em>, with an implementation
* by the Hibernate Metamodel Generator. * generated automatically by the Hibernate Metamodel Generator.
* <p> * <p>
* For example: * For example, suppose the entity {@code Book} is defined as follows:
* <pre>
* &#64;Entity
* class Book {
* &#64;Id String isbn;
* String title;
* ...
* }
* </pre>
* <p>
* Then we might define:
* <pre> * <pre>
* &#064;Find * &#064;Find
* Book getBookForIsbn(String isbn); * Book getBookForIsbn(String isbn);
@ -28,6 +38,55 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
* List&lt;Book&gt; getBooksWithTitle(String title); * List&lt;Book&gt; getBooksWithTitle(String title);
* </pre> * </pre>
* <p> * <p>
* Notice that:
* <ul>
* <li>the types and names of the method parameters exactly match the
* types and names of the corresponding fields of the entity.
* <li>there's no special naming convention for the {@code @Find}
* methods&mdash;they may be named arbitrarily, and their names
* encode no semantics.
* </ul>
* <p>
* The Metamodel Generator automatically creates an "implementation"
* of every finder method in the static metamodel class {@code Books_}.
* The generated method may be called according to the following
* protocol:
* <pre>
* Book book = Books_.findBookByIsbn(session, isbn);
* List&lt;Book&gt; books = Books_.getBooksWithTitle(session, String title);
* </pre>
* <p>
* Notice the extra parameter of type {@code EntityManager} at the
* start of the parameter list.
* <p>
* Alternatively, the type to which the annotated method belongs may
* also declare an abstract method with no parameters which returns
* one of the types {@link jakarta.persistence.EntityManager},
* {@link org.hibernate.StatelessSession},
* or {@link org.hibernate.Session}, for example:
* <pre>
* EntityManager entityManager();
* </pre>
* In this case:
* <ul>
* <li>the generated method is no longer {@code static},
* <li>the generated method will use this method to obtain the
* session object, instead of having a parameter of type
* {@code EntityManager}, and
* <li>the generated static metamodel class will actually implement
* the type which declares the method annotated {@code @SQL}.
* </ul>
* <p>
* Thus, the generated method may be called according to the following
* protocol:
* <pre>
* Books books = new Books_(session);
* Book book = books.getBookForIsbn(isbn);
* List&lt;Book&gt; books = books.getBooksWithTitle(String title);
* </pre>
* <p>
* This is reminiscent of traditional DAO-style repositories.
* <p>
* The return type of an annotated method must be an entity type {@code E}, * The return type of an annotated method must be an entity type {@code E},
* or one of the following types: * or one of the following types:
* <ul> * <ul>
@ -47,7 +106,7 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
* {@link jakarta.persistence.EntityManager#find(Class, Object)} * {@link jakarta.persistence.EntityManager#find(Class, Object)}
* to retrieve the entity. * to retrieve the entity.
* <li>If the parameters match exactly with the {@code @NaturalId} * <li>If the parameters match exactly with the {@code @NaturalId}
* fieldd of the entity, the finder method uses * field of the entity, the finder method uses
* {@link org.hibernate.Session#byNaturalId(Class)} to retrieve the * {@link org.hibernate.Session#byNaturalId(Class)} to retrieve the
* entity. * entity.
* <li>Otherwise, the finder method builds and executes a * <li>Otherwise, the finder method builds and executes a
@ -55,6 +114,9 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
* query}. * query}.
* </ul> * </ul>
* *
* @see HQL
* @see SQL
*
* @author Gavin King * @author Gavin King
* @since 6.3 * @since 6.3
*/ */

View File

@ -17,8 +17,8 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
/** /**
* Identifies a method of an abstract class or interface as defining * Identifies a method of an abstract class or interface as defining
* the signature of a method which is used to execute the given * the signature of a method which is used to execute the given
* {@linkplain #value HQL query}, and is generated automatically by * {@linkplain #value HQL query}, with an implementation generated
* the Hibernate Metamodel Generator. * automatically by the Hibernate Metamodel Generator.
* <p> * <p>
* For example: * For example:
* <pre> * <pre>
@ -36,11 +36,44 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
* <p> * <p>
* The Metamodel Generator automatically creates an "implementation" * The Metamodel Generator automatically creates an "implementation"
* of these methods in the static metamodel class {@code Books_}. * of these methods in the static metamodel class {@code Books_}.
* The generated methods may be called according to the following
* protocol:
* <pre> * <pre>
* Book book = Books_.findBookByIsbn(session, isbn); * Book book = Books_.findBookByIsbn(session, isbn);
* List&lt;Book&gt; books = Books_.findBooksByTitleWithPagination(session, pattern, 10, 0); * List&lt;Book&gt; books = Books_.findBooksByTitleWithPagination(session, pattern, 10, 0);
* </pre> * </pre>
* <p> * <p>
* Notice the extra parameter of type {@code EntityManager} at the
* start of the parameter list.
* <p>
* Alternatively, the type to which the annotated method belongs may
* also declare an abstract method with no parameters which returns
* one of the types {@link jakarta.persistence.EntityManager},
* {@link org.hibernate.StatelessSession},
* or {@link org.hibernate.Session}, for example:
* <pre>
* EntityManager entityManager();
* </pre>
* In this case:
* <ul>
* <li>the generated method is no longer {@code static},
* <li>the generated method will use this method to obtain the
* session object, instead of having a parameter of type
* {@code EntityManager}, and
* <li>the generated static metamodel class will actually implement
* the type which declares the method annotated {@code @SQL}.
* </ul>
* <p>
* Thus, the generated methods may be called according to the following
* protocol:
* <pre>
* Books books = new Books_(session);
* Book book = books.findBookByIsbn(isbn);
* List&lt;Book&gt; books = books.findBooksByTitleWithPagination(pattern, 10, 0);
* </pre>
* <p>
* This is reminiscent of traditional DAO-style repositories.
* <p>
* The return type of an annotated method must be: * The return type of an annotated method must be:
* <ul> * <ul>
* <li>an entity type, * <li>an entity type,
@ -73,6 +106,9 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
* the Metamodel Generator, and so it isn't necessary to specify the * the Metamodel Generator, and so it isn't necessary to specify the
* {@link CheckHQL} annotation. * {@link CheckHQL} annotation.
* *
* @see SQL
* @see Find
*
* @author Gavin King * @author Gavin King
* @since 6.3 * @since 6.3
*/ */

View File

@ -17,8 +17,8 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
/** /**
* Identifies a method of an abstract class or interface as defining * Identifies a method of an abstract class or interface as defining
* the signature of a method which is used to execute the given * the signature of a method which is used to execute the given
* {@linkplain #value SQL query}, and is generated automatically by * {@linkplain #value SQL query}, with an implementation generated
* the Hibernate Metamodel Generator. * automatically by the Hibernate Metamodel Generator.
* <p> * <p>
* For example: * For example:
* <pre> * <pre>
@ -36,11 +36,44 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
* <p> * <p>
* The Metamodel Generator automatically creates an "implementation" * The Metamodel Generator automatically creates an "implementation"
* of these methods in the static metamodel class {@code Books_}. * of these methods in the static metamodel class {@code Books_}.
* The generated methods may be called according to the following
* protocol:
* <pre> * <pre>
* Book book = Books_.findBookByIsbn(session, isbn); * Book book = Books_.findBookByIsbn(session, isbn);
* List&lt;Book&gt; books = Books_.findBooksByTitleWithPagination(session, pattern, 10, 0); * List&lt;Book&gt; books = Books_.findBooksByTitleWithPagination(session, pattern, 10, 0);
* </pre> * </pre>
* <p> * <p>
* Notice the extra parameter of type {@code EntityManager} at the
* start of the parameter list.
* <p>
* Alternatively, the type to which the annotated method belongs may
* also declare an abstract method with no parameters which returns
* one of the types {@link jakarta.persistence.EntityManager},
* {@link org.hibernate.StatelessSession},
* or {@link org.hibernate.Session}, for example:
* <pre>
* EntityManager entityManager();
* </pre>
* In this case:
* <ul>
* <li>the generated method is no longer {@code static},
* <li>the generated method will use this method to obtain the
* session object, instead of having a parameter of type
* {@code EntityManager}, and
* <li>the generated static metamodel class will actually implement
* the type which declares the method annotated {@code @SQL}.
* </ul>
* <p>
* Thus, the generated methods may be called according to the following
* protocol:
* <pre>
* Books books = new Books_(session);
* Book book = books.findBookByIsbn(isbn);
* List&lt;Book&gt; books = books.findBooksByTitleWithPagination(pattern, 10, 0);
* </pre>
* <p>
* This is reminiscent of traditional DAO-style repositories.
* <p>
* The return type of an annotated method must be: * The return type of an annotated method must be:
* <ul> * <ul>
* <li>an entity type, * <li>an entity type,
@ -59,6 +92,9 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
* the method parameter {@code name}. * the method parameter {@code name}.
* </ul> * </ul>
* *
* @see HQL
* @see Find
*
* @author Gavin King * @author Gavin King
* @since 6.3 * @since 6.3
*/ */