1. Overview

In this short tutorial, we’ll shed light on how to solve the Hibernate QueryException: “named parameter not bound”.

First, we’ll elucidate the main cause behind the exception. Then, we’ll demonstrate how to reproduce it, and finally, we’ll learn how to fix it.

2. Understanding the Exception

Before jumping to the solution, let’s try to understand what the exception and its stack trace mean.

In short, Hibernate throws QueryException to signal an error when translating a Hibernate query to SQL due to an invalid syntax. Therefore, the stack trace “named parameter not bound” indicates that Hibernate fails to bind a named parameter specified in a particular query.

Typically, a named parameter is prefixed with a colon (:) and followed by a placeholder for the actual value that needs to be set before executing the query:

SELECT p FROM Person p WHERE p.firstName = :firstName;

One of the most common causes of our exception is forgetting to assign a value for a named parameter in a Hibernate query.

3. Reproducing the Exception

Now that we know what is the leading cause of the exception, let’s go down the rabbit hole and see how to reproduce it using a practical example.

First, let’s consider the Person entity class:

@Entity
public class Person {

    @Id
    private int id;
    private String firstName;
    private String lastName;

   // standard getters and setters
}

Here, the @Entity annotation denotes that our class is an entity that maps a table in the database. Furthermore, @Id indicates that the id property represents the primary key.

Now, let’s create a Hibernate query with a named parameter and pretend to forget to set a value for our parameter:

@Test
void whenNotSettingValueToNamedParameter_thenThrowQueryException() {
    Exception exception = assertThrows(QueryException.class, () -> {
        Query<Person> query = session.createQuery("FROM Person p WHERE p.firstName = :firstName", Person.class);
        query.list();
    });

    String expectedMessage = "Named parameter not bound";
    String actualMessage = exception.getMessage();

    assertTrue(actualMessage.contains(expectedMessage));
}

As we can see, the test case fails with QueryException: “named parameter not bound”. The reason here is that Hibernate doesn’t know anything about the named parameter firstName and expects this parameter to be set before executing the query.

4. Fixing the Exception

The solution to avoid QueryException in this case is to assign a value to the named parameter before executing the query. To do so, we can use the setParameter() method:

@Test
void whenSettingValueToNamedParameter_thenDoNotThrowQueryException() {
    Query<Person> query = session.createQuery("FROM Person p WHERE p.firstName = :firstName", Person.class);
    query.setParameter("firstName", "Azhrioun");

    assertNotNull(query.list());
}

As shown above, the test case passes with success. The setParameter() call tells Hibernate which value to use for our named parameter when executing the query.

5. Conclusion

In this short article, we explained what causes Hibernate to throw QueryException: “named parameter not bound”. Then, we illustrated using a practical example how to reproduce the exception and how to fix it.

As always, the full source code of the examples is available over on GitHub.

Course – LSD (cat=Persistence)

Get started with Spring Data JPA through the reference Learn Spring Data JPA course:

>> CHECK OUT THE COURSE
res – Persistence (eBook) (cat=Persistence)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.