Sie sind auf Seite 1von 5

Hibernate with PostgreSQL

Mappings: Primary Keys


When you use Hibernate with a PostgreSQL database, you should use
the SEQUENCE strategy to generate primary key values. This
strategy uses a simple database sequence and is well supported and
optimized by PostgreSQL and Hibernate.
If you want to use Hibernate’s default sequence, you just need to add
a @GeneratedValue annotation to your primary key attribute and set
the strategy to GenerationType.SEQUENCE.

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id", updatable = false, nullable = false)
private Long id;

Or you can create a custom sequence and define the mapping with a
@SequenceGenerator.

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "book_generator")
@SequenceGenerator(name="book_generator",
sequenceName = "book_seq")
@Column(name = "id", updatable = false, nullable = false)
private Long id;

www.thoughts-on-java.org
Hibernate with PostgreSQL
Mappings: Custom data types
PostgreSQL supports a set proprietary data types which Hibernate
doesn’t map by default. Popular examples for that are the JSON and
JSONB data types which allow you to persist and query JSON
documents in a PostgreSQL database.
If you want to use these types with Hibernate, you need to define the
mapping yourself. That is not as complicated as it might sound. You
just need to implement and register a UserType which tells
Hibernate how to map the Java object to a supported JDBC type and
vice versa.
I explained the required implementation in great detail in How to use
PostgreSQL’s JSONB data type with Hibernate. You can use the same
approach to implement a custom mapping for all PostgreSQL types
that are not supported by Hibernate.

Mappings: Read-only Views


From a mapping point of view, database tables and views are pretty
similar and you can map both of them to an entity class.
By default, Hibernate supports read and write operations for all
entities. If you want to make an entity read-only, you have to tell
Hibernate that it is immutable. You can do that by annotating the
entity class with an @Immutable annotation.

@Entity
@Immutable
public class BookView { … }

www.thoughts-on-java.org
Hibernate with PostgreSQL
Queries: Use database PostgreSQL-specific query features
Native SQL queries allow you to use the full SQL feature set including
all database specific query features. You create them in a similar way
as your JPQL queries. You can define a named native query with a
@NamedNativeQuery annotation or create an ad-hoc native query by
calling the createNativeQuery method on the EntityManager.

@NamedNativeQuery(name = "selectAuthorNames",
query = "SELECT a.firstname, a.lastname FROM Author a")

Query q = em.createNativeQuery(
"SELECT a.firstname, a.lastname FROM Author a");
List<Object[]> authors = q.getResultList();

Queries: Call PostgreSQL-specific SQL functions


The JPQL function function allows you to call any SQL function
supported by your database. You just need to provide the name of
the function as the first parameter, followed by an optional list of
parameters that will be used to call the SQL function.
The following code snippet shows a simple example that calls the
SQL function calculate with the parameters 1 and 2.

Author a = em.createQuery("SELECT a FROM Author a "


+ “WHERE a.id = function('calculate', 1, 2)",
Author.class).getSingleResult();

www.thoughts-on-java.org
Hibernate with PostgreSQL
Queries: Call custom PostgreSQL functions
When your PostgreSQL function returns an REF_CURSOR
parameter, which is a cursor on a result set, you need to call it like a
stored procedure.
Since JPA 2.1, you can call a stored procedure with a
@NamedStoredProcedureQuery or an ad-hoc
StoredProcedureQuery.

@NamedStoredProcedureQuery
With a @NamedStoredProcedureQuery annotation you can define a
function call which you can use in your business code. The following
code snippet defines a call of the get_reviews function. It tells
Hibernate to provide an input parameter of type Long and to expect
an REF_CURSOR as a result. The resultClass parameter tells
Hibernate to map all records of the REF_CURSOR to Review objects.

@NamedStoredProcedureQuery(
name = "getReviews",
procedureName = "get_reviews",
resultClasses = Review.class,
parameters = {
@StoredProcedureParameter(
mode = ParameterMode.REF_CURSOR,
type = void.class),
@StoredProcedureParameter(
mode = ParameterMode.IN,
type = Long.class)
}
)

www.thoughts-on-java.org
Hibernate with PostgreSQL
You can call the @NamedStoredProcedureQuery in a similar way as
you would call a @NamedQuery. You just need to call the
createNamedStoredProcedureQuery method to instantiate the
query, set the input parameters and retrieve the result.

StoredProcedureQuery q =
this.em.createNamedStoredProcedureQuery("getReviews");
q.setParameter(2, b.getId());
List<Review> reviews = q.getResultList();

Ad-hoc StoredProcedureQuery
You first need to call the createStoredProcedureQuery method of the
EntityManager with the name of the database function and its return
type, to instantiate a StoredProcedureQuery. In the next step, you
need to register all function parameters. You can do that by calling
the registerStoredProcedureParameter method of the
StoredProcedureQuery for each parameter.
After you defined the function call, you just need to provide the
values for all input parameters and execute the query by calling the
getResultList method on the StoredProcedureQuery.

StoredProcedureQuery query =
this.em.createStoredProcedureQuery("get_reviews",
Review.class);
query.registerStoredProcedureParameter(1, void.class,
ParameterMode.REF_CURSOR);
query.registerStoredProcedureParameter(2, Long.class,
ParameterMode.IN);

query.setParameter(2, b.getId());
List<Review> reviews = query.getResultList();

www.thoughts-on-java.org

Das könnte Ihnen auch gefallen