I have been working on a tricky case where the customer had developed a custom DBTransactionFactory, following instructions from the article "Creating and Using a Custom DBTransaction Implementation" from Steve Muench.
It was working fine and the application was correctly using the custom DBTransactionFactory.
However, after customer deployed another application in the same Web Container and also using its own custom DBTransactionFactory, he noticed that the second application was using the same DBTransactionFactory (same class and same instance) as the first application.
After investigation, development pointed out that TransactionFactory has a MetaObjectManager scope, as shown when executing the following command:
java -cp <JDev_Home>BC4Jlibbc4jmt.jar oracle.jbo.common.PropertyManager
---------------------------------------------------------------
Business Components for Java - System Properties
---------------------------------------------------------------
Properties loaded from following sources, in order:
1. Client environment
2. Applet tags
3. -D flags (appear in System.properties)
4. bc4j.properties file (in current directory)
5. /oracle/jbo/BC4J.properties resource
6. /oracle/jbo/commom.jboserver.properties resource
7. /oracle/jbo/common.Diagnostic.properties resource
8. System defined default
---------------------------------------------------------------
...
TransactionFactory MetaObjectManager (M)public Internal
...
---------------------------------------------------------------
As explained in the JDeveloper online help, topic "Understanding Configuration Property Scopes":
...
You'll see each property is listed with one of the following scopes:
* MetaObjectManager
Properties at this scope are initialized once per Java VM when the ADF PropertyManager is first initialized.
...
If
you leave any MetaObjectManager-scoped properties in your bc4j.xcfg
files, you will have the undesirable behavior that they will take on
the value specified in the configuration of the first application
module whose pool gets created after the Java VM starts up.
...
We could force each application using its own version of TransactionFactory by adding code to the latter part of each ApplicationModuleImpl.
In Application 1, that should use CustomDatabaseTransactionFactory1, f.ex.:
In Application 2, that should use CustomDatabaseTransactionFactory2, f.ex.:
...
static
{
oracle.jbo.server.DatabaseTransactionFactory.setFactory(new CustomDatabaseTransactionFactory1());
}
...
static
{
oracle.jbo.server.DatabaseTransactionFactory.setFactory(new CustomDatabaseTransactionFactory2());
}