2020-03-31

Hibernate JPA @Column Example

@Column

The @Column annotation is used to specify the mapping between a basic entity attribute and the database table column.

JPA defines rules for implicitly determining the name of tables and columns. For a detailed discussion of implicit naming see Naming.

For basic type attributes, the implicit naming rule is that the column name is the same as the attribute name. If that implicit naming rule does not meet your requirements, you can explicitly tell Hibernate (and other providers) the column name to use.

Explicit column naming

@Entity(name = "Product")
public class Product {

@Id
private Integer id;

private String sku;

private String name;

@Column( name = "NOTES" )
private String description;
}

Here we use @Column to explicitly map the description attribute to the NOTES column, as opposed to the implicit column name description.

Hibernate JPA @CollectionTable Example

@CollectionTable

The @CollectionTable annotation is used to specify the database table that stores the values of a basic or an embeddable type collection.

@CollectionTable is used for the mapping of collections of basic or embeddable types. Applied to the collection-valued field or property.
By default, the columns of the collection table that correspond to the embeddable class or basic type are derived from the attributes of the embeddable class or from the basic type according to the default values of the Column annotation. In the case of a basic type, the column name is derived from the name of the collection-valued field or property. In the case of an embeddable class, the column names are derived from the field or property names of the embeddable class.

To override the default properties of the column used for a basic type, the Column annotation is used on the collection-valued attribute in addition to the ElementCollection annotation.
To override these defaults for an embeddable class, the AttributeOverride and/or AttributeOverrides annotations can be used in addition to the ElementCollection annotation. If the embeddable class contains references to other entities, the default values for the columns corresponding to those references may be overridden by means of the AssociationOverride and/or AssociationOverrides annotations.
If the CollectionTable annotation is missing, the default values of the CollectionTable annotation elements apply.

    Example:

    @Embeddable public class Address {
       protected String street;
       protected String city;
       protected String state;
       ...
     }

    @Entity public class Person {
       @Id protected String ssn;
       protected String name;
       protected Address home;
       ...
       @ElementCollection  // use default table (PERSON_NICKNAMES)
       @Column(name="name", length=50)
       protected Set<String> nickNames = new HashSet();
       ...
    }

    @Entity public class WealthyPerson extends Person {
       @ElementCollection
       @CollectionTable(name="HOMES") // use default join column name
       @AttributeOverrides({
          @AttributeOverride(name="street",
                             column=@Column(name="HOME_STREET")),
          @AttributeOverride(name="city",
                             column=@Column(name="HOME_CITY")),
          @AttributeOverride(name="state",
                             column=@Column(name="HOME_STATE"))
        })
       protected Set<Address> vacationHomes = new HashSet();
       ...
    }

Hibernate JPA @Cacheable Example

@Cacheable

The @Cacheable annotation is used to specify whether an entity should be stored in the second-level cache.

If the persistence.xml shared-cache-mode XML attribute is set to ENABLE_SELECTIVE, then only the entities annotated with the @Cacheable are going to be stored in the second-level cache.

If shared-cache-mode XML attribute value is DISABLE_SELECTIVE, then the entities marked with the @Cacheable annotation are not going to be stored in the second-level cache, while all the other entities are stored in the cache.

The value of the Cacheable annotation is inherited by subclasses; it can be overridden by specifying Cacheable on a subclass.

Cacheable(false) means that the entity and its state must not be cached by the provider.

Learn About Caching



Hibernate JPA Caching

Caching

At runtime, Hibernate handles moving data into and out of the second-level cache in response to the operations performed by the Session, which acts as a transaction-level cache of persistent data. Once an entity becomes managed, that object is added to the internal cache of the current persistence context (EntityManager or Session). The persistence context is also called the first-level cache, and it’s enabled by default.


Hibernate JPA @Basic Example

@Basic

The @Basic annotation is used to map a basic attribute type to a database column.

Basic value types usually map a single database column, to a single, non-aggregated Java type. Hibernate provides a number of built-in basic types, which follow the natural mappings recommended by the JDBC specifications.

Internally Hibernate uses a registry of basic types when it needs to resolve a specific org.hibernate.type.Type.

The simplest type of mapping to a database column. The Basic annotation can be applied to a persistent property or instance variable of any of the following types: Java primitive types, wrappers of the primitive types, String, java.math.BigInteger, java.math.BigDecimal, java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time, java.sql.Timestamp, byte[], Byte[], char[], Character[], enums, and any other type that implements java.io.Serializable.
The use of the Basic annotation is optional for persistent fields and properties of these types. If the Basic annotation is not specified for such a field or property, the default values of the Basic annotation will apply.

    Example 1:

    @Basic
    protected String name;

    Example 2:

    @Basic(fetch=LAZY)
    protected String getName() { return name; }

see more about basic
https://docs.jboss.org/hibernate/orm/6.0/userguide/html_single/Hibernate_User_Guide.html#basic

Hibernate JPA @AttributeOverrides Example

The @AttributeOverrides is used to group several @AttributeOverride annotations.

@AttributeOverrides used to override mappings of multiple properties or fields.


Example:

    @Embedded
    @AttributeOverrides({
            @AttributeOverride(name="startDate", 
                               column=@Column("EMP_START")),
            @AttributeOverride(name="endDate", 
                               column=@Column("EMP_END"))
    })
    public EmploymentPeriod getEmploymentPeriod() { ... }

Hibernate JPA @AttributeOverride Example

The @AttributeOverride annotation is used to override an attribute mapping inherited from a mapped superclass or an embeddable.
When AttributeOverride is applied to a map, "key." or "value." must be used to prefix the name of the attribute that is being overridden in order to specify it as part of the map key or map value.

To override mappings at multiple levels of embedding, a dot (".") notation form must be used in the name element to indicate an attribute within an embedded attribute. The value of each identifier used with the dot notation is the name of the respective embedded field or property.

If AttributeOverride is not specified, the column is mapped the same as in the original mapping.

Example 1:

    @MappedSuperclass
    public class Employee {
        @Id protected Integer id;
        @Version protected Integer version;
        protected String address;
        public Integer getId() { ... }
        public void setId(Integer id) { ... }
        public String getAddress() { ... }
        public void setAddress(String address) { ... }
    }

    @Entity
    @AttributeOverride(name="address", column=@Column(name="ADDR"))
    public class PartTimeEmployee extends Employee {
        // address field mapping overridden to ADDR
        protected Float wage();
        public Float getHourlyWage() { ... }
        public void setHourlyWage(Float wage) { ... }
    }


    Example 2:

    @Embeddable public class Address {
        protected String street;
        protected String city;
        protected String state;
        @Embedded protected Zipcode zipcode;
    }

    @Embeddable public class Zipcode {
        protected String zip;
        protected String plusFour;
    }

    @Entity public class Customer {
        @Id protected Integer id;
        protected String name;
        @AttributeOverrides({
            @AttributeOverride(name="state",
                               column=@Column(name="ADDR_STATE")),
            @AttributeOverride(name="zipcode.zip",
                               column=@Column(name="ADDR_ZIP"))
        })
        @Embedded protected Address address;
        ...
    }


    Example 3:

    @Entity public class PropertyRecord {
        @EmbeddedId PropertyOwner owner;
        @AttributeOverrides({
            @AttributeOverride(name="key.street",
                               column=@Column(name="STREET_NAME")),
            @AttributeOverride(name="value.size",
                               column=@Column(name="SQUARE_FEET")),
            @AttributeOverride(name="value.tax",
                               column=@Column(name="ASSESSMENT"))
        })
       @ElementCollection
       Map<Address, PropertyInfo> parcels;
    }

    @Embeddable public class PropertyInfo {
        Integer parcelNumber;
        Integer size;
        BigDecimal tax;
    }

Hibernate JPA @AssociationOverrides Example

The @AssociationOverrides is used to group several @AssociationOverride annotations.

@Target(value={TYPE,METHOD,FIELD})
@Retention(value=RUNTIME)
public @interface AssociationOverrides
Used to override mappings of multiple relationship properties or fields.
   
    Example:

    @MappedSuperclass
    public class Employee {
    
        @Id protected Integer id;
        @Version protected Integer version;
        @ManyToOne protected Address address;
        @OneToOne protected Locker locker;
    
        public Integer getId() { ... }
        public void setId(Integer id) { ... }
        public Address getAddress() { ... }
        public void setAddress(Address address) { ... }
        public Locker getLocker() { ... }
        public void setLocker(Locker locker) { ... }
        ...
    }
    
    @Entity
    @AssociationOverrides({
        @AssociationOverride(
                   name="address", 
                   joinColumns=@JoinColumn("ADDR_ID")),
        @AttributeOverride(
                   name="locker", 
                   joinColumns=@JoinColumn("LCKR_ID"))
        })
    public PartTimeEmployee { ... }

Hibernate JPA @AssociationOverride Example

The @AssociationOverride annotation is used to override an association mapping (e.g. @ManyToOne, @OneToOne, @OneToMany, @ManyToMany) inherited from a mapped superclass or an embeddable.

JPA defines the @AttributeOverride annotation to handle this scenario. This way, the mapping conflict is resolved by setting up explicit name-based property-column type mappings.

If an Embeddable type is used multiple times in some entity, you need to use the @AttributeOverride and @AssociationOverride annotations to override the default column names defined by the Embeddable.

Considering you have the following Publisher embeddable type which defines a @ManyToOne association with the Country entity:

Embeddable type with a @ManyToOne association

@Embeddable
public static class Publisher {

private String name;

@ManyToOne(fetch = FetchType.LAZY)
private Country country;

//Getters and setters, equals and hashCode methods omitted for brevity

}

@Entity(name = "Country")
public static class Country {

@Id
@GeneratedValue
private Long id;

@NaturalId
private String name;

//Getters and setters are omitted for brevity
}
create table Country (
    id bigint not null,
    name varchar(255),
    primary key (id)
)

alter table Country
    add constraint UK_p1n05aafu73sbm3ggsxqeditd
    unique (name)

Overriding embeddable type attributes
@Entity(name = "Book")
@AttributeOverrides({
@AttributeOverride(
name = "ebookPublisher.name",
column = @Column(name = "ebook_publisher_name")
),
@AttributeOverride(
name = "paperBackPublisher.name",
column = @Column(name = "paper_back_publisher_name")
)
})
@AssociationOverrides({
@AssociationOverride(
name = "ebookPublisher.country",
joinColumns = @JoinColumn(name = "ebook_publisher_country_id")
),
@AssociationOverride(
name = "paperBackPublisher.country",
joinColumns = @JoinColumn(name = "paper_back_publisher_country_id")
)
})
public static class Book {

@Id
@GeneratedValue
private Long id;

private String title;

private String author;

private Publisher ebookPublisher;

private Publisher paperBackPublisher;

//Getters and setters are omitted for brevity
}
create table Book (
    id bigint not null,
    author varchar(255),
    ebook_publisher_name varchar(255),
    paper_back_publisher_name varchar(255),
    title varchar(255),
    ebook_publisher_country_id bigint,
    paper_back_publisher_country_id bigint,
    primary key (id)
)

alter table Book
    add constraint FKm39ibh5jstybnslaoojkbac2g
    foreign key (ebook_publisher_country_id)
    references Country

alter table Book
    add constraint FK7kqy9da323p7jw7wvqgs6aek7
    foreign key (paper_back_publisher_country_id)
    references Country

Hibernate JPA @Access Example

The @Access annotation is used to specify the access type of the associated entity class, mapped superclass, or embeddable class, or entity attribute.

As a JPA provider, Hibernate can introspect both the entity attributes (instance fields) or the accessors (instance properties). By default, the placement of the @Id annotation gives the default access strategy. When placed on a field, Hibernate will assume field-based access. When placed on the identifier getter, Hibernate will use property-based access.

Field-based access

@Entity(name = "Book")
public static class Book {

@Id
private Long id;

private String title;

private String author;

//Getters and setters are omitted for brevity
}

When using field-based access, adding other entity-level methods is much more flexible because Hibernate won’t consider those part of the persistence state. To exclude a field from being part of the entity persistent state, the field must be marked with the @Transient annotation.

Another advantage of using field-based access is that some entity attributes can be hidden from outside the entity.

An example of such attribute is the entity @Version field, which, usually, does not need to be manipulated by the data access layer.

With field-based access, we can simply omit the getter and the setter for this version field, and Hibernate can still leverage the optimistic concurrency control mechanism.

Property-based access

@Entity(name = "Book")
public static class Book {

private Long id;

private String title;

private String author;

@Id
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}
}

When using property-based access, Hibernate uses the accessors for both reading and writing the entity state. Every other method that will be added to the entity (e.g. helper methods for synchronizing both ends of a bidirectional one-to-many association) will have to be marked with the @Transient annotation.


2020-03-29

Spring @DynamicPropertySource example

The TestContext framework provides support for dynamic property sources via the @DynamicPropertySource annotation. This annotation can be used in integration tests that need to add properties with dynamic values to the set of PropertySources in the Environment for the ApplicationContext loaded for the integration test.

The @DynamicPropertySource annotation and its supporting infrastructure were originally designed to allow properties from Testcontainers based tests to be exposed easily to Spring integration tests. However, this feature may also be used with any form of external resource whose lifecycle is maintained outside the test’s ApplicationContext.

In contrast to the @TestPropertySource annotation that is applied at the class level, @DynamicPropertySource must be applied to a static method that accepts a single DynamicPropertyRegistry argument which is used to add name-value pairs to the Environment. Values are dynamic and provided via a Supplier which is only invoked when the property is resolved. Typically, method references are used to supply values, as can be seen in the following example which uses the Testcontainers project to manage a Redis container outside of the Spring ApplicationContext. The IP address and port of the managed Redis container are made available to components within the test’s ApplicationContext via the redis.host and redis.port properties. These properties can be injected into Spring-managed components via @Value("${redis.host}") and @Value("${redis.port}"), respectively.

@SpringJUnitConfig(/* ... */)
@Testcontainers
class ExampleIntegrationTests {

    @Container
    static RedisContainer redis = new RedisContainer();

    @DynamicPropertySource
    static void redisProperties(DynamicPropertyRegistry registry) {
        registry.add("redis.host", redis::getContainerIpAddress);
        registry.add("redis.port", redis::getMappedPort);
    }

    // tests ...

}


The use of @ContextConfiguration and the ApplicationContextInitializer can be replaced with a static @DynamicPropertySource method that serves the same purpose. If we make these changes to the integration test class shown above, it now looks like the following:

@SpringBootTest
@Testcontainers
class ExampleIntegrationTests {

    @Container
    static Neo4jContainer<?> neo4j = new Neo4jContainer<>();

    @DynamicPropertySource
    static void neo4jProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.data.neo4j.uri", neo4j::getBoltUrl);
    }

}

2020-03-25

Spring - ResourceLoader Example

ResourceLoader

The ResourceLoader interface is meant to be implemented by objects that can return (that is, load) Resource instances. The following listing shows the ResourceLoader interface definition:

public interface ResourceLoader {

    Resource getResource(String location);
}

All application contexts implement the ResourceLoader interface. Therefore, all application contexts may be used to obtain Resource instances.

When you call getResource() on a specific application context, and the location path specified doesn’t have a specific prefix, you get back a Resource type that is appropriate to that particular application context. For example, assume the following snippet of code was executed against a ClassPathXmlApplicationContext instance:

Resource template = ctx.getResource("some/resource/path/myTemplate.txt");

Against a ClassPathXmlApplicationContext, that code returns a ClassPathResource. If the same method were executed against a FileSystemXmlApplicationContext instance, it would return a FileSystemResource. For a WebApplicationContext, it would return a ServletContextResource. It would similarly return appropriate objects for each context.

As a result, you can load resources in a fashion appropriate to the particular application context.

On the other hand, you may also force ClassPathResource to be used, regardless of the application context type, by specifying the special classpath: prefix, as the following example shows:

Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");

Similarly, you can force a UrlResource to be used by specifying any of the standard java.net.URL prefixes. The following pair of examples use the file and http prefixes:

Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
Resource template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt");

Spring - InputStreamResource

An InputStreamResource is a Resource implementation for a given InputStream. It should be used only if no specific Resource implementation is applicable. In particular, prefer ByteArrayResource or any of the file-based Resource implementations where possible.

In contrast to other Resource implementations, this is a descriptor for an already-opened resource. Therefore, it returns true from isOpen(). Do not use it if you need to keep the resource descriptor somewhere or if you need to read a stream multiple times.

Spring - ServletContextResource

This is a Resource implementation for ServletContext resources that interprets relative paths within the relevant web application’s root directory.

It always supports stream access and URL access but allows java.io.File access only when the web application archive is expanded and the resource is physically on the filesystem. Whether or not it is expanded and on the filesystem or accessed directly from the JAR or somewhere else like a database (which is conceivable) is actually dependent on the Servlet container.


Spring - FileSystemResource

This is a Resource implementation for java.io.File and java.nio.file.Path handles. It supports resolution as a File and as a URL.

Spring - ClassPathResource

This class represents a resource that should be obtained from the classpath. It uses either the thread context class loader, a given class loader, or a given class for loading resources.

This Resource implementation supports resolution as java.io.File if the class path resource resides in the file system but not for classpath resources that reside in a jar and have not been expanded (by the servlet engine or whatever the environment is) to the filesystem. To address this, the various Resource implementations always support resolution as a java.net.URL.

A ClassPathResource is created by Java code by explicitly using the ClassPathResource constructor but is often created implicitly when you call an API method that takes a String argument meant to represent a path. For the latter case, a JavaBeans PropertyEditor recognizes the special prefix, classpath:, on the string path and creates a ClassPathResource in that case.

Spring - UrlResource

UrlResource

UrlResource wraps a java.net.URL and can be used to access any object that is normally accessible with a URL, such as files, an HTTP target, an FTP target, and others. All URLs have a standardized String representation, such that appropriate standardized prefixes are used to indicate one URL type from another. This includes file: for accessing filesystem paths, http: for accessing resources through the HTTP protocol, ftp: for accessing resources through FTP, and others.

A UrlResource is created by Java code by explicitly using the UrlResource constructor but is often created implicitly when you call an API method that takes a String argument meant to represent a path. For the latter case, a JavaBeans PropertyEditor ultimately decides which type of Resource to create. If the path string contains well-known (to it, that is) prefix (such as classpath:), it creates an appropriate specialized Resource for that prefix. However, if it does not recognize the prefix, it assume the string is a standard URL string and creates a UrlResource.


Instantiating the Spring Container by Using AnnotationConfigApplicationContext

This versatile ApplicationContext implementation is capable of accepting not only @Configuration classes as input but also plain @Component classes and classes annotated.

Spring’s AnnotationConfigApplicationContext introduced in Spring 3.0.


When @Configuration classes are provided as input, the @Configuration class itself is registered as a bean definition and all declared @Bean methods within the class are also registered as bean definitions.

When @Component and JSR-330 classes are provided, they are registered as bean definitions, and it is assumed that DI metadata such as @Autowired or @Inject are used within those classes where necessary.

Simple Construction
In much the same way that Spring XML files are used as input when instantiating a ClassPathXmlApplicationContext, you can use @Configuration classes as input when instantiating an AnnotationConfigApplicationContext. This allows for completely XML-free usage of the Spring container, as the following example shows:

public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
    MyService myService = ctx.getBean(MyService.class);
    myService.doStuff();
}

As mentioned earlier, AnnotationConfigApplicationContext is not limited to working only with @Configuration classes. Any @Component or JSR-330 annotated class may be supplied as input to the constructor, as the following example shows:

public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(MyServiceImpl.class, Dependency1.class, Dependency2.class);
    MyService myService = ctx.getBean(MyService.class);
    myService.doStuff();
}

The preceding example assumes that MyServiceImpl, Dependency1, and Dependency2 use Spring dependency injection annotations such as @Autowired.

Building the Container Programmatically by Using register(Class<?>…​)
You can instantiate an AnnotationConfigApplicationContext by using a no-arg constructor and then configure it by using the register() method. This approach is particularly useful when programmatically building an AnnotationConfigApplicationContext. The following example shows how to do so:

public static void main(String[] args) {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.register(AppConfig.class, OtherConfig.class);
    ctx.register(AdditionalConfig.class);
    ctx.refresh();
    MyService myService = ctx.getBean(MyService.class);
    myService.doStuff();
}

Spring - @Bean vs @Configuration

The @Bean annotation is used to indicate that a method instantiates, configures, and initializes a new object to be managed by the Spring IoC container. For those familiar with Spring’s <beans/> XML configuration, the @Bean annotation plays the same role as the <bean/> element. You can use @Bean-annotated methods with any Spring @Component. However, they are most often used with @Configuration beans.

Annotating a class with @Configuration indicates that its primary purpose is as a source of bean definitions. Furthermore, @Configuration classes let inter-bean dependencies be defined by calling other @Bean methods in the same class. The simplest possible @Configuration class reads as follows:

@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }
}

The preceding AppConfig class is equivalent to the following Spring <beans/> XML:

<beans>
    <bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>

Full @Configuration vs “lite” @Bean mode?

When @Bean methods are declared within classes that are not annotated with @Configuration, they are referred to as being processed in a “lite” mode. Bean methods declared in a @Component or even in a plain old class are considered to be “lite”, with a different primary purpose of the containing class and a @Bean method being a sort of bonus there. For example, service components may expose management views to the container through an additional @Bean method on each applicable component class. In such scenarios, @Bean methods are a general-purpose factory method mechanism.

Unlike full @Configuration, lite @Bean methods cannot declare inter-bean dependencies. Instead, they operate on their containing component’s internal state and, optionally, on arguments that they may declare. Such a @Bean method should therefore not invoke other @Bean methods. Each such method is literally only a factory method for a particular bean reference, without any special runtime semantics. The positive side-effect here is that no CGLIB subclassing has to be applied at runtime, so there are no limitations in terms of class design (that is, the containing class may be final and so forth).

In common scenarios, @Bean methods are to be declared within @Configuration classes, ensuring that “full” mode is always used and that cross-method references therefore get redirected to the container’s lifecycle management. This prevents the same @Bean method from accidentally being invoked through a regular Java call, which helps to reduce subtle bugs that can be hard to track down when operating in “lite” mode.

Spring @Named

If you would like to use a qualified name for the dependency that should be injected, you should use the @Named annotation, as the following example shows:

import javax.inject.Inject;
import javax.inject.Named;

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Inject
    public void setMovieFinder(@Named("main") MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // ...
}

Spring - Dependency Injection with @Inject

@Inject


Instead of @Autowired, you can use @javax.inject.Inject as follows:

import javax.inject.Inject;

public class SimpleTestInject {

    private MovieFinder movieFinder;

    @Inject
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    public void listMovies() {
        this.movieFinder.findMovies(...);
        // ...
    }
}

with @Autowired, you can use @Inject at the field level, method level and constructor-argument level.

Spring - StringUtils split example

split(String toSplit, String delimiter)

Split a String at the first occurrence of the delimiter.

Method:

public static String[] split(@Nullable String toSplit, @Nullable String delimiter)


Example:

String[] list = StringUtils.split("Hello1, Hello2", ",");


Split a String at the first occurrence of the delimiter. Does not include the delimiter in the result.

Parameters:

toSplit - the string to split (potentially null or empty)
delimiter - to split the string up with (potentially null or empty)

Returns:

a two element array with index 0 being before the delimiter, and index 1 being after the delimiter (neither element includes the delimiter); or null if the delimiter wasn't found in the given input String

Spring - StringUtils isEmpty example

isEmpty(Object str)

Check whether the given object (possibly a String) is empty.

This method accepts any Object as an argument, comparing it to null and the empty String. As a consequence, this method will never return true for a non-null non-String object.

The Object signature is useful for general attribute handling code that commonly deals with Strings but generally has to iterate over Objects since attributes may e.g. be primitive value objects as well.

Method:


public static boolean isEmpty(@Nullable Object str)

Example:


 StringUtils.isEmpty(null) = true
 StringUtils.isEmpty("") = true
 StringUtils.isEmpty("Hello") = false



2020-03-24

Java - Parallel Array Sorting

Current sorting implementations provided by the Java Collections Framework (Collections.sort and Arrays.sort) all perform the sorting operation sequentially in the calling thread.

This enhancement will offer the same set of sorting operations currently provided by the Arrays class

Example:

public class Arrays {

  ...
  public static void parallelSort(byte[] a) { ... }
  public static void parallelSort(byte[] a, int fromIndex, int toIndex)
  public static void parallelSort(short[] a) { ... }
  public static void parallelSort(short[] a, int fromIndex, int toIndex)
    {...}

  ...

}


2020-03-21

Hibernate Architecture

Hibernate Architecture


Hibernate, as an ORM solution, effectively "sits between" the Java application data access layer and the Relational Database. The Java application makes use of the Hibernate APIs to manipulate its domain data.



As a JPA provider, Hibernate implements the Java Persistence API specifications and the association between JPA interfaces and Hibernate specific implementations can be visualized in the following diagram:


SessionFactory (org.hibernate.SessionFactory)
A thread-safe (and immutable) representation of the mapping of the application domain model to a database. Acts as a factory for org.hibernate.Session instances. The EntityManagerFactory is the JPA equivalent of a SessionFactory and basically, those two converge into the same SessionFactory implementation.

A SessionFactory is very expensive to create, so, for any given database, the application should have only one associated SessionFactory. The SessionFactory maintains services that Hibernate uses across all Session(s) such as second level caches, connection pools, transaction system integrations, etc.

Session (org.hibernate.Session)
A single-threaded, short-lived object conceptually modeling a "Unit of Work" PoEAA. In JPA nomenclature, the Session is represented by an EntityManager.

Behind the scenes, the Hibernate Session wraps a JDBC java.sql.Connection and acts as a factory for org.hibernate.Transaction instances. It maintains a generally "repeatable read" persistence context (first level cache) of the application domain model.

Transaction (org.hibernate.Transaction)
A single-threaded, short-lived object used by the application to demarcate individual physical transaction boundaries. EntityTransaction is the JPA equivalent and both act as an abstraction API to isolate the application from the underlying transaction system in use (JDBC or JTA).

Hibernate - In predicate

In predicate

IN predicates performs a check that a particular value is in a list of values. Its syntax is:

in_expression ::=
    single_valued_expression [NOT] IN single_valued_list

single_valued_list ::=
    constructor_expression | (subquery) | collection_valued_input_parameter

constructor_expression ::= (expression[, expression]*)

In HQL, single_valued_expression can refer to a far more broad set of expression types. Single-valued association are allowed, and so are component/embedded attributes, although that feature depends on the level of support for tuple or "row value constructor syntax" in the underlying database. Additionally, HQL does not limit the value type in any way, though application developers should be aware that different types may incur limited support based on the underlying database vendor. This is largely the reason for the JPQL limitations.

The list of values can come from a number of different sources. In the constructor_expression and collection_valued_input_parameter, the list of values must not be empty; it must contain at least one value.

In predicate examples

List<Payment> payments = entityManager.createQuery(
"select p " +
"from Payment p " +
"where type(p) in ( CreditCardPayment, WireTransferPayment )", Payment.class )
.getResultList();

List<Phone> phones = entityManager.createQuery(
"select p " +
"from Phone p " +
"where type in ( 'MOBILE', 'LAND_LINE' )", Phone.class )
.getResultList();

List<Phone> phones = entityManager.createQuery(
"select p " +
"from Phone p " +
"where type in :types", Phone.class )
.setParameter( "types", Arrays.asList( PhoneType.MOBILE, PhoneType.LAND_LINE ) )
.getResultList();

List<Phone> phones = entityManager.createQuery(
"select distinct p " +
"from Phone p " +
"where p.person.id in (" +
" select py.person.id " +
" from Payment py" +
" where py.completed = true and py.amount > 50 " +
")", Phone.class )
.getResultList();

// Not JPQL compliant!
List<Phone> phones = entityManager.createQuery(
"select distinct p " +
"from Phone p " +
"where p.person in (" +
" select py.person " +
" from Payment py" +
" where py.completed = true and py.amount > 50 " +
")", Phone.class )
.getResultList();

// Not JPQL compliant!
List<Payment> payments = entityManager.createQuery(
"select distinct p " +
"from Payment p " +
"where ( p.amount, p.completed ) in (" +
" (50, true )," +
" (100, true )," +
" (5, false )" +
")", Payment.class )
.getResultList();

Hibernate - Between predicate

Between predicate

Analogous to the SQL BETWEEN expression, it checks if the value is within boundaries. All the operands should have comparable types.

Between predicate examples

List<Person> persons = entityManager.createQuery(
"select p " +
"from Person p " +
"join p.phones ph " +
"where p.id = 1L and index(ph) between 0 and 3", Person.class )
.getResultList();

List<Person> persons = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.createdOn between '1999-01-01' and '2001-01-02'", Person.class )
.getResultList();

List<Call> calls = entityManager.createQuery(
"select c " +
"from Call c " +
"where c.duration between 5 and 20", Call.class )
.getResultList();

List<Person> persons = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name between 'H' and 'M'", Person.class )
.getResultList();

Hibernate - Like predicate

Like predicate

Performs a like comparison on string values. The syntax is:

like_expression ::=
    string_expression
    [NOT] LIKE pattern_value
    [ESCAPE escape_character]

The semantics follow that of the SQL like expression. The pattern_value is the pattern to attempt to match in the string_expression. Just like SQL, pattern_value can use _ and % as wildcards. The meanings are the same. The _ symbol matches any single character and % matches any number of characters.

Like predicate examples

List<Person> persons = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like 'Jo%'", Person.class )
.getResultList();

List<Person> persons = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name not like 'Jo%'", Person.class )
.getResultList();
The optional escape 'escape character' is used to specify an escape character used to escape the special meaning of _ and % in the pattern_value. This is useful when needing to search on patterns including either _ or %.

The syntax is formed as follows: 'like_predicate' escape 'escape_symbol' So, if | is the escape symbol and we want to match all stored procedures prefixed with Dr_, the like criteria becomes: 'Dr|_%' escape '|':

Like with escape symbol

// find any person with a name starting with "Dr_"
List<Person> persons = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like 'Dr|_%' escape '|'", Person.class )
.getResultList();

Hibernate - Order by Example

Order by

The results of the query can also be ordered. The ORDER BY clause is used to specify the selected values to be used to order the result. The types of expressions considered valid as part of the ORDER BY clause include:

  • state fields
  • component/embeddable attributes
  • scalar expressions such as arithmetic operations, functions, etc.
  • identification variable declared in the select clause for any of the previous expression types

Additionally, JPQL says that all values referenced in the ORDER BY clause must be named in the SELECT clause. HQL does not mandate that restriction, but applications desiring database portability should be aware that not all databases support referencing values in the ORDER BY clause that are not referenced in the select clause.

Individual expressions in the order-by can be qualified with either ASC (ascending) or DESC (descending) to indicate the desired ordering direction. Null values can be placed in front or at the end of the sorted set using NULLS FIRST or NULLS LAST clause respectively.

Order by example

List<Person> persons = entityManager.createQuery(
"select p " +
"from Person p " +
"order by p.name", Person.class )
.getResultList();

List<Object[]> personTotalCallDurations = entityManager.createQuery(
"select p.name, sum( c.duration ) as total " +
"from Call c " +
"join c.phone ph " +
"join ph.person p " +
"group by p.name " +
"order by total", Object[].class )
.getResultList();

Hibernate - Group by Example

Group by

The GROUP BY clause allows building aggregated results for various value groups. As an example, consider the following queries:

Group by example

Long totalDuration = entityManager.createQuery(
"select sum( c.duration ) " +
"from Call c ", Long.class )
.getSingleResult();

List<Object[]> personTotalCallDurations = entityManager.createQuery(
"select p.name, sum( c.duration ) " +
"from Call c " +
"join c.phone ph " +
"join ph.person p " +
"group by p.name", Object[].class )
.getResultList();

//It's even possible to group by entities!
List<Object[]> personTotalCallDurations = entityManager.createQuery(
"select p, sum( c.duration ) " +
"from Call c " +
"join c.phone ph " +
"join ph.person p " +
"group by p", Object[].class )
.getResultList();

The first query retrieves the complete total of all orders. The second retrieves the total for each customer, grouped by each customer.

In a grouped query, the where clause applies to the non-aggregated values (essentially it determines whether rows will make it into the aggregation). The HAVING clause also restricts results, but it operates on the aggregated values. In the Group by example, we retrieved Call duration totals for all persons. If that ended up being too much data to deal with, we might want to restrict the results to focus only on customers with a summed total of more than 1000:

Having example

List<Object[]> personTotalCallDurations = entityManager.createQuery(
"select p.name, sum( c.duration ) " +
"from Call c " +
"join c.phone ph " +
"join ph.person p " +
"group by p.name " +
"having sum( c.duration ) > 1000", Object[].class )
.getResultList();

The HAVING clause follows the same rules as the WHERE clause and is also made up of predicates. HAVING is applied after the groupings and aggregations have been done, while the WHERE clause is applied before.

Hibernate - Polymorphism

HQL and JPQL queries are inherently polymorphic.

List<Payment> payments = entityManager.createQuery(
"select p " +
"from Payment p ", Payment.class )
.getResultList();

This query names the Payment entity explicitly. However, all subclasses of Payment are also available to the query. So, if the CreditCardPayment and WireTransferPayment entities extend the Payment class, all three types would be available to the entity query, and the query would return instances of all three.

This behavior can be altered in two ways:

by limiting the query to select only from the subclass entity

by using either the org.hibernate.annotations.Polymorphism annotation (global, and Hibernate-specific). See the @Polymorphism section for more info about this use case.

The HQL query from java.lang.Object is totally valid (although not very practical from a performance perspective)!

It returns every object of every entity type defined by your application mappings.

Hibernate - (HQL and JPQL) Distinct

Distinct

For JPQL and HQL, DISTINCT has two meanings:

It can be passed to the database so that duplicates are removed from a result set

It can be used to filter out the same parent entity references when join fetching a child collection

Using DISTINCT with SQL projections

For SQL projections, DISTINCT needs to be passed to the database because the duplicated entries need to be filtered out before being returned to the database client.

Using DISTINCT with projection queries example

         List<String> lastNames = entityManager.createQuery(
"select distinct p.lastName " +
"from Person p", String.class)
.getResultList();
When running the query above, Hibernate generates the following SQL query:

SELECT DISTINCT
    p.last_name as col_0_0_
FROM person p
For this particular use case, passing the DISTINCT keyword from JPQL/HQL to the database is the right thing to do.

Using DISTINCT with entity queries
DISTINCT can also be used to filter out entity object references when fetching a child association along with the parent entities.

Using DISTINCT with entity queries example

List<Person> authors = entityManager.createQuery(
"select distinct p " +
"from Person p " +
"left join fetch p.books", Person.class)
.getResultList();
In this case, DISTINCT is used because there can be multiple Books entities associated with a given Person. If in the database there are 3 Persons in the database and each person has 2 Books, without DISTINCT this query will return 6 Persons since the SQL-level result-set size is given by the number of joined Book records.

However, the DISTINCT keyword is passed to the database as well:

SELECT DISTINCT
    p.id as id1_1_0_,
    b.id as id1_0_1_,
    p.first_name as first_na2_1_0_,
    p.last_name as last_nam3_1_0_,
    b.author_id as author_i3_0_1_,
    b.title as title2_0_1_,
    b.author_id as author_i3_0_0__,
    b.id as id1_0_0__
FROM person p
LEFT OUTER JOIN book b ON p.id=b.author_id
In this case, the DISTINCT SQL keyword is undesirable since it does a redundant result set sorting, as explained in this blog post. To fix this issue, Hibernate 5.2.2 added support for the HINT_PASS_DISTINCT_THROUGH entity query hint:

Using DISTINCT with entity queries example

List<Person> authors = entityManager.createQuery(
"select distinct p " +
"from Person p " +
"left join fetch p.books", Person.class)
.setHint( QueryHints.HINT_PASS_DISTINCT_THROUGH, false )
.getResultList();
With this entity query hint, Hibernate will not pass the DISTINCT keyword to the SQL query:

SELECT
    p.id as id1_1_0_,
    b.id as id1_0_1_,
    p.first_name as first_na2_1_0_,
    p.last_name as last_nam3_1_0_,
    b.author_id as author_i3_0_1_,
    b.title as title2_0_1_,
    b.author_id as author_i3_0_0__,
    b.id as id1_0_0__
FROM person p
LEFT OUTER JOIN book b ON p.id=b.author_id
When using the HINT_PASS_DISTINCT_THROUGH entity query hint, Hibernate can still remove the duplicated parent-side entities from the query result.

Hibernate - (HQL and JPQL) Implicit joins (path expressions)

Another means of adding to the scope of object model types available to the query is through the use of implicit joins or path expressions.


Simple implicit join example

List<Phone> phones = entityManager.createQuery(
"select ph " +
"from Phone ph " +
"where ph.person.address = :address ", Phone.class )
.setParameter( "address", address )
.getResultList();

// same as
List<Phone> phones = entityManager.createQuery(
"select ph " +
"from Phone ph " +
"join ph.person pr " +
"where pr.address = :address ", Phone.class )
.setParameter( "address", address)
.getResultList();

Reused implicit join

List<Phone> phones = entityManager.createQuery(
"select ph " +
"from Phone ph " +
"where ph.person.address = :address " +
"  and ph.person.createdOn > :timestamp", Phone.class )
.setParameter( "address", address )
.setParameter( "timestamp", timestamp )
.getResultList();

//same as
List<Phone> phones = entityManager.createQuery(
"select ph " +
"from Phone ph " +
"inner join ph.person pr " +
"where pr.address = :address " +
"  and pr.createdOn > :timestamp", Phone.class )
.setParameter( "address", address )
.setParameter( "timestamp", timestamp )
.getResultList();

Hibernate - (HQL and JPQL) Explicit joins

The FROM clause can also contain explicit relationship joins using the join keyword. These joins can be either inner or left outer style joins.


Explicit inner join examples

List<Person> persons = entityManager.createQuery(
"select distinct pr " +
"from Person pr " +
"join pr.phones ph " +
"where ph.type = :phoneType", Person.class )
.setParameter( "phoneType", PhoneType.MOBILE )
.getResultList();

// same query but specifying join type as 'inner' explicitly
List<Person> persons = entityManager.createQuery(
"select distinct pr " +
"from Person pr " +
"inner join pr.phones ph " +
"where ph.type = :phoneType", Person.class )
.setParameter( "phoneType", PhoneType.MOBILE )
.getResultList();

Explicit left (outer) join examples

List<Person> persons = entityManager.createQuery(
"select distinct pr " +
"from Person pr " +
"left join pr.phones ph " +
"where ph is null " +
"   or ph.type = :phoneType", Person.class )
.setParameter( "phoneType", PhoneType.LAND_LINE )
.getResultList();

// functionally the same query but using the 'left outer' phrase
List<Person> persons = entityManager.createQuery(
"select distinct pr " +
"from Person pr " +
"left outer join pr.phones ph " +
"where ph is null " +
"   or ph.type = :phoneType", Person.class )
.setParameter( "phoneType", PhoneType.LAND_LINE )
.getResultList();

HQL WITH clause join example

List<Object[]> personsAndPhones = session.createQuery(
"select pr.name, ph.number " +
"from Person pr " +
"left join pr.phones ph with ph.type = :phoneType " )
.setParameter( "phoneType", PhoneType.LAND_LINE )
.list();


JPQL ON clause join example

List<Object[]> personsAndPhones = entityManager.createQuery(
"select pr.name, ph.number " +
"from Person pr " +
"left join pr.phones ph on ph.type = :phoneType " )
.setParameter( "phoneType", PhoneType.LAND_LINE )
.getResultList();

Fetch join example

// functionally the same query but using the 'left outer' phrase
List<Person> persons = entityManager.createQuery(
"select distinct pr " +
"from Person pr " +
"left join fetch pr.phones ", Person.class )
.getResultList();

Hibernate - (HQL and JPQL) FROM clause

The FROM clause

The FROM clause is responsible for defining the scope of object model types available to the rest of the query. It is also responsible for defining all the "identification variables" available to the rest of the query.

Hibernate - (HQL and JPQL) Insert statements

Insert statements

HQL adds the ability to define INSERT statements as well.

There is no JPQL equivalent to HQL-style INSERT statements.

HQL INSERT statement is:

insert_statement ::=
    insert_clause select_statement

insert_clause ::=
    INSERT INTO entity_name (attribute_list)

attribute_list ::=
    state_field[, state_field ]*

The attribute_list is analogous to the column specification in the SQL INSERT statement. For entities involved in mapped inheritance, only attributes directly defined on the named entity can be used in the attribute_list. Superclass properties are not allowed and subclass properties do not make sense. In other words, INSERT statements are inherently non-polymorphic.

select_statement can be any valid HQL select query, with the caveat that the return types must match the types expected by the insert. Currently, this is checked during query compilation rather than allowing the check to relegate to the database. This may cause problems between Hibernate Types which are equivalent as opposed to equal. For example, this might cause lead to issues with mismatches between an attribute mapped as a org.hibernate.type.DateType and an attribute defined as a org.hibernate.type.TimestampType, even though the database might not make a distinction or might be able to handle the conversion.

For the id attribute, the insert statement gives you two options. You can either explicitly specify the id property in the attribute_list, in which case its value is taken from the corresponding select expression, or omit it from the attribute_list in which case a generated value is used. This latter option is only available when using id generators that operate "in the database"; attempting to use this option with any "in memory" type generators will cause an exception during parsing.

For optimistic locking attributes, the insert statement again gives you two options. You can either specify the attribute in the attribute_list in which case its value is taken from the corresponding select expressions or omit it from the attribute_list in which case the seed value defined by the corresponding org.hibernate.type.VersionType is used.

INSERT query statements

int insertedEntities = session.createQuery(
"insert into Partner (id, name) " +
"select p.id, p.name " +
"from Person p ")
.executeUpdate();

Hibernate - (HQL and JPQL) Delete statements

Delete statements

DELETE statements is the same in HQL and JPQL:

delete_statement ::=
    delete_clause [where_clause]

delete_clause ::=
    DELETE FROM entity_name [[AS] identification_variable]


A DELETE statement is also executed using the executeUpdate() method of either org.hibernate.query.Query or javax.persistence.Query.

Hibernate - (HQL and JPQL) Update statements

UPDATE statements is the same in HQL and JPQL:

update_statement ::=
    update_clause [where_clause]

update_clause ::=
    UPDATE entity_name [[AS] identification_variable]
    SET update_item {, update_item}*

update_item ::=
    [identification_variable.]{state_field | single_valued_object_field} = new_value

new_value ::=
    scalar_expression | simple_entity_expression | NULL

UPDATE query statements
int updatedEntities = entityManager.createQuery(
"update Person p " +
"set p.name = :newName " +
"where p.name = :oldName" )
.setParameter( "oldName", oldName )
.setParameter( "newName", newName )
.executeUpdate();

int updatedEntities = session.createQuery(
"update Person " +
"set name = :newName " +
"where name = :oldName" )
.setParameter( "oldName", oldName )
.setParameter( "newName", newName )
.executeUpdate();

int updatedEntities = session.createQuery(
"update versioned Person " +
"set name = :newName " +
"where name = :oldName" )
.setParameter( "oldName", oldName )
.setParameter( "newName", newName )
.executeUpdate();

Hibernate - (HQL and JPQL) Select statements

SELECT statements in HQL is:

select_statement :: =
    [select_clause]
    from_clause
    [where_clause]
    [groupby_clause]
    [having_clause]
    [orderby_clause]

The simplest possible HQL SELECT statement is of the form:


List<Person> persons = session.createQuery("from Person" ).list();

The select statement in JPQL is exactly the same as for HQL except that JPQL requires a select_clause, whereas HQL does not.

List<Person> persons = entityManager.createQuery(
"select p " +
"from Person p", Person.class )
.getResultList();

Even though HQL does not require the presence of a select_clause, it is generally good practice to include one. For simple queries the intent is clear and so the intended result of the select_clause is easy to infer. But on more complex queries that is not always the case.

It is usually better to explicitly specify intent. Hibernate does not actually enforce that a select_clause be present even when parsing JPQL queries, however, applications interested in JPA portability should take heed of this.

Hibernate - HQL and JPQL Query API (Hibernate Query API)

In Hibernate, the HQL query is represented as org.hibernate.query.Query which is obtained from a Session. If the HQL is a named query, Session#getNamedQuery would be used; otherwise Session#createQuery is needed.


Obtaining a Hibernate Query

org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name"
);


Obtaining a Hibernate Query reference for a named query

org.hibernate.query.Query query = session.getNamedQuery( "get_person_by_name" );

Basic Query usage - Hibernate

org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
// timeout - in seconds
.setTimeout( 2 )
// write to L2 caches, but do not read from them
.setCacheMode( CacheMode.REFRESH )
// assuming query cache was enabled for the SessionFactory
.setCacheable( true )
// add a comment to the generated SQL if enabled via the hibernate.use_sql_comments configuration property
.setComment( "+ INDEX(p idx_person_name)" );


Hibernate name parameter binding

org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%", StringType.INSTANCE );
Hibernate generally understands the expected type of the parameter given its context in the query. In the previous example since we are using the parameter in a LIKE comparison against a String-typed attribute Hibernate would automatically infer the type; so the above could be simplified.

Hibernate name parameter binding (inferred type)

org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" );

Hibernate name parameter binding (short forms)

org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name " +
"  and p.createdOn > :timestamp" )
.setParameter( "name", "J%" )
.setParameter( "timestamp", timestamp, TemporalType.TIMESTAMP);

Hibernate list() result

List<Person> persons = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" )
.list();

Hibernate uniqueResult()

Person person = (Person) session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" )
.uniqueResult();

Scrolling through a ResultSet containing entities

try ( ScrollableResults scrollableResults = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" )
.scroll()
) {
while(scrollableResults.next()) {
Person person = (Person) scrollableResults.get();
process(person);
}
}


Hibernate stream() using a projection result type

try ( Stream<Object[]> persons = session.createQuery(
"select p.name, p.nickName " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" )
.stream() ) {

persons
.map( row -> new PersonNames(
(String) row[0],
(String) row[1] ) )
.forEach( this::process );
}

Hibernate stream() using an entity result type

try( Stream<Person> persons = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" )
.stream() ) {

Map<Phone, List<Call>> callRegistry = persons
.flatMap( person -> person.getPhones().stream() )
.flatMap( phone -> phone.getCalls().stream() )
.collect( Collectors.groupingBy( Call::getPhone ) );

process(callRegistry);
}

Hibernate - HQL and JPQL Query API (JPA Query API)

When using Hibernate, you can execute entity queries either via JPA or the Hibernate-specific API. the query API was also merged, and now the Hibernate org.hibernate.query.Query interface extends the JPA javax.persistence.Query.

Next, we are going to see how the query API differs between the standard JPA interfaces and the Hibernate-specific API.

JPA Query API

In JPA, the query is represented by javax.persistence.Query or javax.persistence.TypedQuery as obtained from the EntityManager. The create an inline Query or TypedQuery, you need to use the EntityManager#createQuery method. For named queries, the EntityManager#createNamedQuery method is needed.

Obtaining a JPA Query or a TypedQuery reference

Query query = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like :name"
);

TypedQuery<Person> typedQuery = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like :name", Person.class
);

Obtaining a JPA Query or a TypedQuery reference for a named query

@NamedQuery(
    name = "get_person_by_name",
    query = "select p from Person p where name = :name"
)

Query query = entityManager.createNamedQuery( "get_person_by_name" );

TypedQuery<Person> typedQuery = entityManager.createNamedQuery(
"get_person_by_name", Person.class
);
Hibernate offers a specific @NamedQuery annotation which provides ways to configure various query features, like flush mode, cacheability, time out interval.

Obtaining a Hibernate Query or a TypedQuery reference for a named query

@NamedQueries({
    @NamedQuery(
        name = "get_phone_by_number",
        query = "select p " +
                "from Phone p " +
                "where p.number = :number",
        timeout = 1,
        readOnly = true
    )
})

Phone phone = entityManager
.createNamedQuery( "get_phone_by_number", Phone.class )
.setParameter( "number", "123-456-7890" )
.getSingleResult();
The Query interface can then be used to control the execution of the query. For example, we may want to specify an execution timeout or control caching.

Basic JPA Query usage

Query query = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
// timeout - in milliseconds
.setHint( "javax.persistence.query.timeout", 2000 )
// flush only at commit time
.setFlushMode( FlushModeType.COMMIT );


JPA name parameter binding

Query query = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" );

// For generic temporal field types (e.g. `java.util.Date`, `java.util.Calendar`)
// we also need to provide the associated `TemporalType`
Query query = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.createdOn > :timestamp" )
.setParameter( "timestamp", timestamp, TemporalType.DATE );

 JPA positional parameter binding

Query query = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like ?1" )
.setParameter( 1, "J%" );

JPA getResultList() result

List<Person> persons = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" )
.getResultList();

JPA getResultList() result

List<Person> persons = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" )
.getResultList();