JBossStandAloneJtaPlatform never uses the WildFlyStandAloneJtaPlatform

Hi everyone!

After upgrading our Wildfly instance from version 9 to 23, we noticed an error that happens when we persist entities. Along with the Wildfly upgrade, we also upgraded Hibernate to 5.3.20.Final.

We have a rather large web application used in the production for years, so I would like to consult the error and correct ways to fix it.

What is happening

I investigated the error and it is happening when both conditions are satisfied:

  • The entity has table-type generated id: @GeneratedValue(strategy = GenerationType.TABLE, generator = "PRIMARY_KEY")
  • The JTA platform is set to the following value in the persistence.xml: <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform" />

This happens when persisting a newly created entity. It happens every time persisting is called.

I am enclosing the minified logs below:

12:12:52,663 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-1) SQL Error: 0, SQLState: null
12:12:52,663 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-1) javax.resource.ResourceException: IJ000460: Error checking for a transaction
12:12:52,669 ERROR [org.jboss.as.ejb3.invocation] (default task-1) WFLYEJB0034: Jakarta Enterprise Beans Invocation failed on component SimpleSessionBean for method public void com.example.SimpleSessionBean.save(java.lang.String): javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.HibernateException: Could not apply work
	...
Caused by: javax.persistence.PersistenceException: org.hibernate.HibernateException: Could not apply work
	...
Caused by: org.hibernate.HibernateException: Could not apply work
	...
Caused by: org.hibernate.exception.GenericJDBCException: unable to obtain isolated JDBC connection
	...
Caused by: java.sql.SQLException: javax.resource.ResourceException: IJ000460: Error checking for a transaction
	...
Caused by: javax.resource.ResourceException: IJ000460: Error checking for a transaction
	...
Caused by: java.lang.IllegalStateException: WFTXN0073: Unexpected provider transaction mismatch; expected TransactionImple < ac, BasicAction: 0:ffff7f000001:75e8b014:6114f41c:f status: ActionStatus.RUNNING >, got TransactionImple < ac, BasicAction: 0:ffff7f000001:75e8b014:6114f41c:17 status: ActionStatus.RUNNING >
	...

I reproduced the error in a minimal application with the properties mentioned above. The error occurs both on MSSQL and PostgreSQL databases. The application can be found in the repository here.

Things that remove the error

I have consulted the error in the JBoss issue tracker here. I found out that we should probably switch from JBossStandAloneJtaPlatform to JBossAppServerJtaPlatform or WildFlyStandAloneJtaPlatform. Both of these options fix the error.

However, I wanted to know some more details about this. I list the questions below.

Question 1 - why is this happening

This is basically a “why” question. :slight_smile: I was wondering if there is a simple way to explain the error. I tried to debug the code and found out that there are two transaction instances per thread and the wrong one is returned in the last point of persisting the entity.

Q1: Is there a way to shortly describe why this error is happening?

Question 2 - why the JBossStandAloneJtaPlatform never really uses the WildFlyStandAloneJtaPlatform

While investigating the error, I looked at the implementation of the JBossStandAloneJtaPlatform in version the hibernate-core-5.3.2.20. As I mentioned above, when it is used, the error with persisting entities is happening. If I switch it to WildFlyStandAloneJtaPlatform, the error disappears.

I will use some shorter names for these classes to make this shorter: JBossStandAloneJtaPlatform → JBossSAJP and WildFlyStandAloneJtaPlatform → WildFlySAJP.

What is surprising for me is that the JBossSAJP seems to first look for the WildFlySAJP (see in the code class JBossStandAloneJtaPlatform line 33).

So, basing on the tests, my expectation would be the following: if WildFlySAJP works when chosen explicitly in the properties, then the JBossSAJP should work too. It still looks for the WildFlySAJP first, yeah?

However, when I debug the JBossSAJP, the search for WildFlySAJP results in an NullPointerException and then it falls back to using the arjuna implementation explicitly instead. It is because the WildFlyStandAloneJtaPlatform wildflyBasedAlternative instance variable stored in the JBossStandAloneJtaPlatform object does not have any serviceRegistry value set.

This is quite surprising for me, looks like a bug. Nobody is setting the serviceRegistry in the wildflyBasedAlternative instance variable. It is important for me, because I suspect that if the WildFlySAJP would really get used, then we would not have the error in the first place. Instead, I probably have to explicitly choose WildFlySAJP in the properties.

Q2: Would you be able to explain this behavior? Is that a bug?