Native Sql Queries in Spring JPA

We added a Tag Cloud in NixMash Spring Posts and so needed to retrieve tags with the number of posts for each tag. Our Hibernate @ManytoMany relationship uses a lookup table. Here's the schema logic.

The SQL Query gets us exactly what we want and looks like this.

Now to use that query in Spring JPA! We're going to go to our Tag Model class and add our @NamedNativeQuery. Notice we give it a name and a resultClass property, which we'll see in action next.

In our Service class we see how to use the @NamedNativeQuery Interface. Notice we add an EntityManager to created our query, where we use its “getTagCloud” name and return a list of populated Tag classes in .getResultList().

The @ManyToMany Issue

Since we nearly always want tags when retrieving a post we defined an EAGER Fetch relationship in our Posts-to-Tags @ManyToMany. This goes both ways in the relationship, so the populated Tag class contains the associated Posts. We obviously don't need the posts for our Tag Cloud, only the number of posts.

If you notice above we're converting our List<Tag> stream with .map(TagDTO::new). Here we'll strip the posts and set our tagCount property.

A Couple of Weirdities

There are two weird issues you may want to know about. First, you saw that the named query in the Tag Model class spanned several lines; thus, line breaks. H2 may not like that so we add a new property to our JPA Configuration.

properties.setProperty(HBM2DDL_IMPORT_FILES_SQL_EXTRACTOR, getH2SqlExtractor());

The HBM2DDL_IMPORT… property is built into Hibernate. The property setting is

org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor

which in NixMash Spring we added to the datasource .properties file.

The second weird issue is the syntax for declaring an identifier in a Native Named Query. Those are Back Quotes around tagCount.

Source Code Notes for this Post

All source code discussed in this post can be found in my NixMash Spring GitHub repo and viewed online here.

Posted July 15, 2016 09:38 AM EDT

More Like This Post