]
Craig Ringer commented on AS7-4552:
-----------------------------------
Stuart: Sorry, missed your comment about the ClassCastException. Here you go:
{code}
21:28:23,794 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-5) MSC00001: Failed
to start service jboss.persistenceunit."AS7TxTest-1.0-SNAPSHOT.war#test-PU":
org.jboss.msc.service.StartException in service
jboss.persistenceunit."AS7TxTest-1.0-SNAPSHOT.war#test-PU": Failed to start
service
at
org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1767)
[jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
[rt.jar:1.7.0_01]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
[rt.jar:1.7.0_01]
at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_01]
Caused by: java.lang.ClassCastException:
org.postgresql.xa.PGXADataSource$$DataSourceProxy2 cannot be cast to javax.sql.DataSource
at
org.jboss.as.jpa.processor.PersistenceUnitDeploymentProcessor$ManagedReferenceFactoryInjector.inject(PersistenceUnitDeploymentProcessor.java:624)
at
org.jboss.as.jpa.processor.PersistenceUnitDeploymentProcessor$ManagedReferenceFactoryInjector.inject(PersistenceUnitDeploymentProcessor.java:613)
at org.jboss.msc.inject.CastingInjector.inject(CastingInjector.java:55)
[jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at
org.jboss.msc.service.ServiceControllerImpl.doInject(ServiceControllerImpl.java:1549)
[jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at
org.jboss.msc.service.ServiceControllerImpl.access$1900(ServiceControllerImpl.java:49)
[jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at
org.jboss.msc.service.ServiceControllerImpl$StartTask.performInjections(ServiceControllerImpl.java:1780)
[jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at
org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1741)
[jboss-msc-1.0.2.GA.jar:1.0.2.GA]
... 3 more
{code}
JBoss AS 7 produces non-transactional (autocommit) EntityManager
within transactional EJB methods when using 3rd party javax.sql.DataSource via
@DataSourceDefinition
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Key: AS7-4552
URL:
https://issues.jboss.org/browse/AS7-4552
Project: Application Server 7
Issue Type: Bug
Components: EJB, JPA / Hibernate, Transactions
Affects Versions: 7.1.1.Final
Environment: java version "1.7.0_01"
Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode)
Linux ayaki.localdomain 3.3.0-4.fc16.x86_64 #1 SMP Tue Mar 20 18:05:40 UTC 2012 x86_64
x86_64 x86_64 GNU/Linux
Reporter: Craig Ringer
Assignee: Scott Marlow
Labels: autocommit, ejb, h2, h2sql, jdbc, jta, postgresql, transaction,
transaction_manager, xa
Attachments: h2-test-logs.zip,
JBossAS7ContainerTransactionsWith3rdPtyDataSource.zip,
JBossAS7ContainerTransactionsWith3rdPtyDataSourceFixed.zip,
JBossAS7ContainerTransactionsWithJBossDataSource.zip, JBossAS7H2Tests.zip
When using a javax.sql.DataSource via @DataSourceDefinition to create the JTA datasource
for a persistence unit, transactional EJB business methods run without transactions. No
warning or error is emitted.
Business method calls annotated @TransactionAttribute(TransactionAttributeType.REQUIRED)
receive an EntityManager that *is in autocommit mode*, ie is *not* in a transaction.
This violates the EJB3 spec and is a nasty problem.
I discovered this when testing some code against PostgreSQL that uses deferred
constraints to create two interdependent database objects; record A must have at least one
record B referencing it, but record B also has a foreign key reference to record A. This
can be satisfied only with deferred constraints, and works fine in SQL-level testing. When
testing with Arquillian at the JBoss AS 7 / Hibernate / JPA level, though, it was
breaking.
Further investigation showed that the entity manager was in autocommit despite the method
being transactional, as demonstrated by a test that tries to create and fetch from a
cursor.
I've now verified that the issue exists when using PostgreSQL or H2 as the database,
so it's not specific to PostgreSQL. I've attached test cases for both databases.
JBoss AS 7 clearly has some validation and checking to do because it *must* not allow an
autocommit entity manager to be injected for transactional business methods. That's a
really critical error, as it effectively means that transaction isolation is always at
DIRTY_READ (which most DBs don't even support) rather than the requested level, and
it's impossible to roll back work!
As a workaround, it should be possible to deploy an archive with an embedded jboss-ds.xml
instead of using @DataSourceDefinition . I haven't tested this - struggling to find
documentation on in-archive deployment of jboss-ds.xml or equivalent jboss-specific
descriptor like a datasource definition for jboss-web.xml .
Using the jboss admin cli, or deploying a jboss datasource definition xml file to the
deployments folder separately to the program archive, isn't subject to the problem.
That's a PITA when unit testing, though.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: