Hibernate 5/javax.persistence vs Hibernate 6/jakarta.persistence

(I posted this in stackoverflow ( java - Hibernate5/javax.persistence vs Hibernate6/jakarta.persistence - Stack Overflow ) but had no answers yet - I wondered whether anyone on here has had a similar issue with upgrading?)

I’ve run into an interesting difference between the above two combinations.

In my code I have something like:

//deals with setting null values in parameterised queries
private static void setTValue(Query aQ,String aCol,LocalTime aValue)
    if (aValue == null)
      //for javax
      //for jakarta
//      aQ.setParameter(aCol,null);
      java.sql.Time t = java.sql.Time.valueOf(aValue);
  catch (Exception e)
    LOG.error("Error converting time value", e);

and then, elsewhere:

org.hibernate.query.Query myQuery = session.createNativeQuery("insert into dbo.mytable (TimeCol) values (:TimeCol)");

I’m using Azure (i.e. cloud version of SQL Server) and TimeCol is of type TIME. This code is used 100s of times in a loop for inserting records. Now, if I use Hibernate 5 (5.6.9.Final) and javax.persistence-api (2.2), along with the line marked “for javax” above, this runs at a certain speed. If I switch to Hibernate 6 (6.0.1.Final) and jakarta.persistence-api (3.1.0), along with the line marked “for jakarta” above, it runs at something like a quarter of the speed.

I can’t work out whether this is due to some change in Hibernate 6 (which claims performance improvements!), or in the switch from javax 2 to jakarta 3.

(Yes, I know the insert could be done using a POJO instead of a native query, but I’d rather not go through changing all that right now - unless that would give a distinct performance improvement? Although I would have thought a native query would inherently be faster than going through Hibernate’s objects? I’m just interested in why there should be such a noticeable difference between Hibernate 5/6 and javax 2/jakarta 3.)

I don’t know how you are measuring this and beware that there are many uncertainties here (DB load, system load), but this might be a performance bug/regression somewhere. The performance improvements in Hibernate 6 come from the fact that extracting values from a result set is now done by position rather than by name. Statements that only do binding/execution should behave similar to what 5.x did. We changed a few other code paths for mutation statements as well though, so maybe we just missed out on certain optimizations in this particular new code path or maybe the native query plan cache is just different in 6. To know for sure, we would need a self contained runnable sample project that we can use for analysis of this matter.

If you could provide us this sample project, we can look into this and hopefully fix the underlying problem.