How to run a custom update using Java JPA

From time to time it is necessary to execute a query without using Java’s JPA infrastructure.

In order to do it, we have to define a NamedQuery to execute. In this example, I will run an update against the database.

@Entity
@NamedQueries ({
    @NamedQuery (
        name = "SomeEntity.TestQuery",
        query = "update SomeEntity se set se.myField = '' where se.id = 0"
    )
})
public class SomeEntity implements Serializable {
    // ...
    private String myField;
    // ...
}

As you can see, the custom query does not use the database table name, but the JPA one. This is usually the name of the class that we have declared as Entity. In this case it is called SomeEntity.

Then we have to create an instance from the named query previously defined and make the call.

public class SomeEntityService {

    private final EntityManager em;

    public SomeEntityService(final EntityManager em) {
        this.em = em;
    }

    public void test() {
        Query query = em.createNamedQuery("SomeEntity.TestQuery");
        em.getTransaction().begin();
        query.executeUpdate();
        em.getTransaction().commit();
    }
}

The important part here is to wrap the executeUpdate() call inside a transaction. Without it we will get the following exception:

Executing an update/delete query javax.persistence.TransactionRequiredException: Executing an update/delete query

Finally, I’m adding a persistence.xml file as a reference. Check the value of the transaction-type attribute.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="PersistenceUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <!-- Connection properties specified in service.properties -->
    </persistence-unit>
</persistence>

Happy coding.

Leave a Reply