Search code examples
javahibernatejpql

Hibernate bulkUpdate() with List as parameters


I have a query like:

@Entity
@Table(name="sparkteams")
@NamedQueries({
        @NamedQuery(name = SparkTeam.DELETE_TEAMS
                , query = "delete from SparkTeam s" +
                " where s.acctId=? and s.teamName in (?)")
})

public class SparkTeam implements Persistent{
    private Long acctId;
    private String teamName;
    // entity class definitions
}

And in my DAO class, I have the following method:

@Override
@Modifying
public void deleteTeams(Long acctId, List<String> teams) {
    getHibernateTemplate().bulkUpdate(
            SparkTeam.DELETE_TEAMS,
            new Object[] {acctId, teams}
);

When the method is called, I get

java.lang.IllegalArgumentException: node to traverse cannot be null!

So it looks like the bulkUpdate() method cannot parse List parameters correctly, I wonder what the correct way is.


Solution

  • You got this error because you are passing the name of a named query as first argument instead of the query string. And if you send your query string it also will fail with ClassCastException. You have to use named parameters instead of "?" to bind multiples values.

    I believe the correct way to do it is using hibernate directly through HibernateCallback. First, change the query to use named parameters:

    " where s.acctId=:p1 and s.teamName in (:p2)")
    

    And then replace the deleteTeams method with:

    public void deleteTeams(final Long acctId, final List<String> teams) {
            HibernateCallback<Integer> deleteCallback = new HibernateCallback<Integer>() {
    
            @Override
            public Integer doInHibernate(Session session)
                    throws HibernateException, SQLException {
    
                return session.getNamedQuery(SparkTeam.DELETE_TEAMS)
                        .setParameter("p1", acctId)
                        .setParameterList("p2", teams)
                        .executeUpdate();
            }
    
        };
        getHibernateTemplate().execute(deleteCallback);
    }