Multiline String literals with Java Text Blocks
Are you struggling with performance issues in your Spring, Jakarta EE, or Java EE application?
What if there were a tool that could automatically detect what caused performance issues in your JPA and Hibernate data access layer?
Wouldn’t it be awesome to have such a tool to watch your application and prevent performance issues during development, long before they affect production systems?
Well, Hypersistence Optimizer is that tool! And it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, Micronaut, or Play Framework.
So, rather than fixing performance issues in your production system on a Saturday night, you are better off using Hypersistence Optimizer to help you prevent those issues so that you can spend your time on the things that you love!
Introduction
In this article, show you how the new Java Text Blocks can help you increase the readability of JPQL, SQL queries, or JSON string values.
Back in 2005, I was developing a .NET project and really liked the C# Verbatim String Literal feature since it allows you to write a multiline string value without having to concatenate each individual line.
The Java 13 Text Blocks feature now offers the possibility of creating a multiline Java String values.
Take a look at how the new #Java Text Blocks can help you increase the readability of JPQL, SQL queries, or JSON string values.https://t.co/wBKLIyb0XF pic.twitter.com/H6VOKW4szH
— Java (@java) March 10, 2020
Java Text Blocks for JPQL or SQL Queries
Whether you are executing a JPQL or an SQL query, without Text Blocks, this is how a query execution would look like when using JPA:
List<Tuple> posts = entityManager
.createNativeQuery(
"SELECT *\n" +
"FROM (\n" +
" SELECT *,\n" +
" dense_rank() OVER (\n" +
" ORDER BY \"p.created_on\", \"p.id\"\n" +
" ) rank\n" +
" FROM (\n" +
" SELECT p.id AS \"p.id\",\n" +
" p.created_on AS \"p.created_on\",\n" +
" p.title AS \"p.title\",\n" +
" pc.id as \"pc.id\",\n" +
" pc.created_on AS \"pc.created_on\",\n" +
" pc.review AS \"pc.review\",\n" +
" pc.post_id AS \"pc.post_id\"\n" +
" FROM post p\n" +
" LEFT JOIN post_comment pc ON p.id = pc.post_id\n" +
" WHERE p.title LIKE :titlePattern\n" +
" ORDER BY p.created_on\n" +
" ) p_pc\n" +
") p_pc_r\n" +
"WHERE p_pc_r.rank <= :rank\n",
Tuple.class)
.setParameter("titlePattern", "High-Performance Java Persistence %")
.setParameter("rank", 5)
.getResultList();
For readability, we don’t want to display the entire query on a single line, so we need to use a multiline String. Prior to Java 13, you’d either use String concatenation or a StringBuilder in order to create a multiline String.
Starting with Java 13, you can use Text Blocks, and, you don’t even have to manually transform the legacy multiline String concatenation to the new multiline text block format. With IntelliJ IDEA, you can press ALT + ENTER and choose the Replace with text block option:

After applying the Replace with text block action, this is how your query can look like:
List<Tuple> posts = entityManager
.createNativeQuery("""
SELECT *
FROM (
SELECT *,
dense_rank() OVER (
ORDER BY "p.created_on", "p.id"
) rank
FROM (
SELECT p.id AS "p.id",
p.created_on AS "p.created_on",
p.title AS "p.title",
pc.id as "pc.id",
pc.created_on AS "pc.created_on",
pc.review AS "pc.review",
pc.post_id AS "pc.post_id"
FROM post p
LEFT JOIN post_comment pc ON p.id = pc.post_id
WHERE p.title LIKE :titlePattern
ORDER BY p.created_on
) p_pc
) p_pc_r
WHERE p_pc_r.rank <= :rank
""",
Tuple.class)
.setParameter("titlePattern", "High-Performance Java Persistence %")
.setParameter("rank", 5)
.getResultList();
The SQL query is way more readable when using Java Text Blocks.
Java Text Blocks for JSON objects
Another place where Java Text Blocks are really useful is when you need to represent JSON, XML, or HTML in your Java code.
Consider the following Book entity that has a JSON properties attribute:
entityManager.persist(
new Book()
.setId(1L)
.setIsbn("978-9730228236")
.setProperties(
"{" +
" \"title\": \"High-Performance Java Persistence\"," +
" \"author\": \"Vlad Mihalcea\"," +
" \"publisher\": \"Amazon\"," +
" \"price\": 44.99," +
" \"reviews\": [" +
" {" +
" \"reviewer\": \"Cristiano\", " +
" \"review\": \"Excellent book to understand Java Persistence\", " +
" \"date\": \"2017-11-14\", " +
" \"rating\": 5" +
" }," +
" {" +
" \"reviewer\": \"T.W\", " +
" \"review\": \"The best JPA ORM book out there\", " +
" \"date\": \"2019-01-27\", " +
" \"rating\": 5" +
" }," +
" {" +
" \"reviewer\": \"Shaikh\", " +
" \"review\": \"The most informative book\", " +
" \"date\": \"2016-12-24\", " +
" \"rating\": 4" +
" }" +
" ]" +
"}"
)
);
When transforming the properties attribute to a text block, the JSON object is unarguably much more readable:
entityManager.persist(
new Book()
.setId(1L)
.setIsbn("978-9730228236")
.setProperties("""
{
"title": "High-Performance Java Persistence",
"author": "Vlad Mihalcea",
"publisher": "Amazon",
"price": 44.99,
"reviews": [
{
"reviewer": "Cristiano",
"review": "Excellent book to understand Java Persistence",
"date": "2017-11-14",
"rating": 5
},
{
"reviewer": "T.W",
"review": "The best JPA ORM book out there",
"date": "2019-01-27",
"rating": 5
},
{
"reviewer": "Shaikh",
"review": "The most informative book",
"date": "2016-12-24",
"rating": 4
}
]
}
"""
)
);
Cool, right?
If you enjoyed this article, I bet you are going to love my Book and Video Courses as well.
Conclusion
Finally, Java has a proper solution to multiline String values. I have switched my High-Performance Java Persistence GitHub repository, as well as the training material for the High-Performance SQL workshop, and the results are spectacular.
Considering that Java 13, 14, 15, and 16 are not LTS (Long-Term Support) releases, most Java projects will probably wait for Java 17 to start adopting this feature. But, for a greenfield project that’s going to launch in production after September 2021 when Java 17 is supposed to be released, it might be a good idea to start the development using Java 14.






