0

I'm trying to create 3 bundles:

  • BundleA: use unmanaged-native hibernate to access database 1.
  • BundleB: also use unmanaged-native hibernate but access database 2.
  • BundleC: imports BundleA and BundleB.

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:

  • Apache Karaf 3.0.1
  • Hibernate 4.2.12.Final

p.s. HibernateUtil class was the Dao class, I changed its name while asking this question. Sorry if it makes any confusion. :(

  • Who is the bundle that export SessionFactory Service? It seems that you get the same service in both daos – Fernando Rincon May 29 '14 at 14:56
  • I get org.hibernate.SessionFactory service from hibernate-osgi bundle. according to [hibernate's document](http://docs.jboss.org/hibernate/orm/4.2/devguide/en-US/html/ch17.html#d5e4990) – Peayton Chen May 30 '14 at 01:25
  • Sorry, don't see from the logging that the wrong configuration file is taken. Maybe you can give some information where you get the conclusion from. – Arie van Wijngaarden Jun 03 '14 at 08:19
  • @ArievanWijngaarden , I edited the post adding the reason why I got the conclusion at the bottom. Thank you :) – Peayton Chen Jun 04 '14 at 02:56
  • I have a question, i am a newbie, but how did you get the mysql driver to work? what is verManagerConnectionProviderImp? – Andrew Phillips Feb 18 '15 at 04:33

1 Answers1

0

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.

  • Thanks for your answer, @ArievanWijngaarden :) I have not thought that may be a bug... I'll try to look deeper into the source code to see if it is. – Peayton Chen Jun 05 '14 at 01:54
  • 1
    You should really try the different location bypass. – Arie van Wijngaarden Jun 05 '14 at 06:32
  • I just tried to place the cfg.xml files in different location and it looks like worked!(The log shows that hibernate reads the config file in the correct locations, although I have not tried to access the dao acturally...). Thanks a lot for your help! – Peayton Chen Jun 05 '14 at 10:24