I'm trying to create 3 bundles:
I expect that bundleA and bundleB will get session factory with their config file. However, Hibernate's log shows that BundleB gets session factory using BundleA's config file.
Does anyone can give me any advise?
BundleA's blueprint.xml:
<bean id="dao" class="idv.peayton.osgi.core.bundle1.Dao" init-method="init" />
<bean id="serviceImpl" class="idv.peayton.osgi.core.bundle1.impl.B1ServiceImpl">
<property name="dao" ref="dao" />
</bean>
<service id="service" ref="serviceImpl" interface="idv.peayton.osgi.core.bundle1.B1Service" />
BundleA's hibernate.cfg.xml:
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/se00001?autoReconnect=true</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<mapping resource="entity/b1.mapping.xml"/>
</session-factory>
BundleB's blueprint.xml:
<bean id="dao" class="idv.peayton.osgi.core.bundle2.Dao" init-method="init" />
<bean id="serviceImpl" class="idv.peayton.osgi.core.bundle2.impl.B2ServiceImpl">
<property name="dao" ref="dao" />
</bean>
<service id="service" ref="serviceImpl" interface="idv.peayton.osgi.core.bundle2.B2Service" />
BundleB's hibernate.cfg.xml: (difference between BundleA is url and mapping resource)
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3307/m00001?autoReconnect=true</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<mapping resource="entity/b2.mapping.xml"/>
</session-factory>
The Dao class looks like below:
public void init() {
logger.info("Initializing session factory...");
if (sf == null) {
Bundle bundle = FrameworkUtil.getBundle(Dao.class);
logger.info("Using bundle: " + bundle);
BundleContext context = bundle.getBundleContext();
logger.info("Using context: " + context);
ServiceReference sr = context.getServiceReference(SessionFactory.class.getName());
logger.info("Using servRef: " + sr);
sf = (SessionFactory) context.getService(sr);
logger.info("SessionFactory is: " + sf);
}
}
And the logs look like below:
2014-05-29 15:33:32,582 | INFO | Local user karaf | HibernateUtil | 206 - peayton-blueprint-core-bundleA - 0.0.1.SNAPSHOT | Initializing session factory...
2014-05-29 15:33:32,582 | INFO | Local user karaf | HibernateUtil | 206 - peayton-blueprint-core-bundleA - 0.0.1.SNAPSHOT | Using bundle: peayton-blueprint-core-bundleA [206]
2014-05-29 15:33:32,582 | INFO | Local user karaf | HibernateUtil | 206 - peayton-blueprint-core-bundleA - 0.0.1.SNAPSHOT | Using context: org.apache.felix.framework.BundleContextImpl@c6e491
2014-05-29 15:33:32,582 | INFO | Local user karaf | HibernateUtil | 206 - peayton-blueprint-core-bundleA - 0.0.1.SNAPSHOT | Using servRef: [org.hibernate.SessionFactory]
2014-05-29 15:33:32,598 | INFO | Local user karaf | Configuration | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000043: Configuring from resource: /hibernate.cfg.xml
2014-05-29 15:33:32,598 | INFO | Local user karaf | Configuration | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000040: Configuration resource: /hibernate.cfg.xml
2014-05-29 15:33:33,707 | INFO | Local user karaf | Configuration | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000221: Reading mappings from resource: entity/b1.mapping.xml
2014-05-29 15:33:35,176 | INFO | Local user karaf | Configuration | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000041: Configured SessionFactory: null
2014-05-29 15:33:35,192 | WARN | Local user karaf | verManagerConnectionProviderImpl | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000402: Using Hibernate built-in connection pool (not for production use!)
2014-05-29 15:33:35,207 | INFO | Local user karaf | verManagerConnectionProviderImpl | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000115: Hibernate connection pool size: 20
2014-05-29 15:33:35,207 | INFO | Local user karaf | verManagerConnectionProviderImpl | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000006: Autocommit mode: false
2014-05-29 15:33:35,207 | INFO | Local user karaf | verManagerConnectionProviderImpl | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://127.0.0.1:3306/se00001?autoReconnect=true]
2014-05-29 15:33:35,207 | INFO | Local user karaf | verManagerConnectionProviderImpl | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000046: Connection properties: {user=username, password=****}
2014-05-29 15:33:35,379 | INFO | Local user karaf | Dialect | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
2014-05-29 15:33:35,426 | INFO | Local user karaf | TransactionFactoryInitiator | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000399: Using default transaction strategy (direct JDBC transactions)
2014-05-29 15:33:35,426 | INFO | Local user karaf | ASTQueryTranslatorFactory | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000397: Using ASTQueryTranslatorFactory
2014-05-29 15:33:35,598 | INFO | Local user karaf | HibernateUtil | 206 - peayton-blueprint-core-bundleA - 0.0.1.SNAPSHOT | SessionFactory is: org.hibernate.internal.SessionFactoryImpl@1a85af4
2014-05-29 15:33:35,598 | INFO | Local user karaf | Dao | 207 - peayton-blueprint-core-bundleB - 1.0.0.SNAPSHOT | Initializing session factory...
2014-05-29 15:33:35,598 | INFO | Local user karaf | Dao | 207 - peayton-blueprint-core-bundleB - 1.0.0.SNAPSHOT | Using bundle: peayton-blueprint-core-bundleB [207]
2014-05-29 15:33:35,598 | INFO | Local user karaf | Dao | 207 - peayton-blueprint-core-bundleB - 1.0.0.SNAPSHOT | Using context: org.apache.felix.framework.BundleContextImpl@866459
2014-05-29 15:33:35,598 | INFO | Local user karaf | Dao | 207 - peayton-blueprint-core-bundleB - 1.0.0.SNAPSHOT | Using servRef: [org.hibernate.SessionFactory]
2014-05-29 15:33:35,629 | INFO | Local user karaf | Configuration | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000043: Configuring from resource: /hibernate.cfg.xml
2014-05-29 15:33:35,629 | INFO | Local user karaf | Configuration | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000040: Configuration resource: /hibernate.cfg.xml
2014-05-29 15:33:35,863 | INFO | Local user karaf | Configuration | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000221: Reading mappings from resource: entity/b1.mapping.xml
2014-05-29 15:33:37,348 | INFO | Local user karaf | Configuration | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000041: Configured SessionFactory: null
2014-05-29 15:33:37,348 | WARN | Local user karaf | verManagerConnectionProviderImpl | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000402: Using Hibernate built-in connection pool (not for production use!)
2014-05-29 15:33:37,348 | INFO | Local user karaf | verManagerConnectionProviderImpl | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000115: Hibernate connection pool size: 20
2014-05-29 15:33:37,348 | INFO | Local user karaf | verManagerConnectionProviderImpl | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000006: Autocommit mode: false
2014-05-29 15:33:37,348 | INFO | Local user karaf | verManagerConnectionProviderImpl | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://127.0.0.1:3306/se00001?autoReconnect=true]
2014-05-29 15:33:37,348 | INFO | Local user karaf | verManagerConnectionProviderImpl | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000046: Connection properties: {user=username, password=****}
2014-05-29 15:33:37,363 | INFO | Local user karaf | Dialect | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
2014-05-29 15:33:37,363 | INFO | Local user karaf | TransactionFactoryInitiator | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000399: Using default transaction strategy (direct JDBC transactions)
2014-05-29 15:33:37,363 | INFO | Local user karaf | ASTQueryTranslatorFactory | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000397: Using ASTQueryTranslatorFactory
2014-05-29 15:33:37,363 | INFO | Local user karaf | Dao | 207 - peayton-blueprint-core-bundleB - 1.0.0.SNAPSHOT | SessionFactory is: org.hibernate.internal.SessionFactoryImpl@88dcd7
Edit: Why I got this conclusion
In bundleA's hibernate.cfg.xml, I tried to read mapping file from entity/b1.mapping.xml. In bundleB, I tried to read mapping file from entity/b2.mapping.xml. But in the log, it looks like that hibernate read mapping file from entity/b1.mapping.xml, in both bundle.
Log of bundldA:
2014-05-29 15:33:33,707 | INFO | Local user karaf | Configuration | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000221: Reading mappings from resource: entity/b1.mapping.xml
Log of bundleB:
2014-05-29 15:33:35,863 | INFO | Local user karaf | Configuration | 110 - org.jboss.logging.jboss-logging - 3.1.0.GA | HHH000221: Reading mappings from resource: entity/b1.mapping.xml
According to this document, I get session factory in Dao class's init method by using SessionFactory service which was exported by hibernate-osgi service. Before calling getService method, I print bundle name to check if I get the wrong bundle, but the bundle name is as my expect.
2014-05-29 15:33:32,582 | INFO | Local user karaf | HibernateUtil | 206 - peayton-blueprint-core-bundleA - 0.0.1.SNAPSHOT | Using bundle: peayton-blueprint-core-bundleA [206]
and
2014-05-29 15:33:35,598 | INFO | Local user karaf | Dao | 207 - peayton-blueprint-core-bundleB - 1.0.0.SNAPSHOT | Using bundle: peayton-blueprint-core-bundleB [207]
My environment is:
p.s. HibernateUtil class was the Dao class, I changed its name while asking this question. Sorry if it makes any confusion. :(
After looking into the code of hibernate-osgi, I concluded that this is a bug in the hibernate-osgi class org.hibernate.osgi.OsgiSessionFactoryService
. You should file a bug there.
For a detailed explanation:
Method getService
from OsgiSessionFactoryService
provides your bundle the SessionFactory
instance. However, for some reasons, this service adds all the bundles that request a session factory to the bundles that are subsequently searched for configuration files. See code here line 85. As a result, the second bundle requesting a session factory will always get the previous configuration.
Although I didn't check this, I think you can bypass this bug by putting your configuration file in a different path in only one of your bundles, for example in /cfg/hibernate.cfg.xml
for bundle A. Since the path differs among the bundles, I assume it will be found by the correct loader.
Hope this helps.