-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Multiple hibernate.cfg.xml files, 2nd one not read?
PostPosted: Tue Mar 28, 2006 6:01 pm 
Newbie

Joined: Wed Jul 28, 2004 1:53 pm
Posts: 5
Location: Boston, MA
Hi,
I have a problem using two libraries that both user Hibernate. Each library includes a hibernate.cfg.xml file in the root of its jar, and each library does the simplest possible hibernate configuration for itself, e.g. sessionFactory = new Configuration().configure().buildSessionFactory().

Both libraries work fine by themselves. But the 3rd library depends on both, and when it issues calls I get Hibernate errors saying classes in the 2nd library are not mapped.

I'm guessing only the first hibernate.cfg.xml file is read, and the 2nd is either not read or ignored because there's already a configuration.

I control the code and configuration for both libraries. What do I need to do in order for the 3rd library to be able to use both? Rename one of the hibernate.cfg.xml files to something else and explicitly include it in the configure() call of the 2nd library?

Any help would be appreciated. Thank you,

Yoav

Hibernate version: 3.1.2

Full stack trace of any exception that occurs:
org.hibernate.hql.ast.QuerySyntaxException: MyClass2 is not mapped. [from MyClass2 as myClass2 where foo = bar]
at org.hibernate.hql.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:157)
at org.hibernate.hql.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:86)
at org.hibernate.hql.ast.tree.FromClause.addFromElement(FromClause.java:70)
at org.hibernate.hql.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:263)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3049)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:2938)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:688)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:544)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:281)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:229)
at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:218)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:158)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:109)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:75)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:54)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:71)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:134)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:113)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1602)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:301)
at $Proxy1.createQuery(Unknown Source)
at com.mycompany.myclass.test(MyClass.java:72)
Name and version of the database you are using: MySQL 5.0.18


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 28, 2006 6:08 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Libraries designed to be used like this shouldn't be configuring themselves. They should make their configurations available to the application code that uses them. Remove the code in the libraries that creates configurations, but leave the .cfg.xml file. Make sure it's in a different package in each jar. Then in every application that uses any of the jars (including their respective main() methods, if they have one) can create one Configuration object, and call cof.configure() on each provided .cfg.xml file.

If the libraries don't need to configure anything unless they're being run as stand-alone applications, you don't even have to load their configurations from your main app(s). Only the mini-app inside the jar needs to do that.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 28, 2006 6:13 pm 
Newbie

Joined: Wed Jul 28, 2004 1:53 pm
Posts: 5
Location: Boston, MA
tenwit wrote:
Libraries designed to be used like this shouldn't be configuring themselves. They should make their configurations available to the application code that uses them. Remove the code in the libraries that creates configurations, but leave the .cfg.xml file. Make sure it's in a different package in each jar. Then in every application that uses any of the jars (including their respective main() methods, if they have one) can create one Configuration object, and call cof.configure() on each provided .cfg.xml file.

If the libraries don't need to configure anything unless they're being run as stand-alone applications, you don't even have to load their configurations from your main app(s). Only the mini-app inside the jar needs to do that.


What you're saying makes sense, thank you. I would appreciate a little more details.

The libraries have a HibernateUtil class like the one shown in the Hibernate reference documentation. That class has a static initializer block which creates the session factory, and a static getSessionFactory() method which the libraries use. What should I do instead? In other wods, how would the HibernateUtil class in the reference documentation be re-written for a library?

Thank you,

Yoav


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 28, 2006 6:56 pm 
Newbie

Joined: Wed Jul 28, 2004 1:53 pm
Posts: 5
Location: Boston, MA
I think I got it... Instead of the reference documentation HibernateUtil I can have something like this:

In each library,
public class HibernateUtil {
private static SessionFactory sessionFactory;

public static void configure(Configuration configuration) {
sessionFactory = configuration.buildSessionFactory();
}

public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}

In the app that uses libraries:
public class Test {
public static void main(String[] args) {
Configuration configuration = new Configuration();
configuration.configure("lib1.cfg.xml");
configuration.configure("lib2.cfg.xml");
Library1.HibernateUtil.configure(configurtaion);
Library2.HibernateUtil.configure(configuration);
}
}

Is that right? I'll go test it out... Thanks again,

Yoav


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 28, 2006 6:56 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
IMO, it shouldn't. These sorts of utility classes cause these sorts of problems. If your library code needs access to the SessionFactory (and it probably shouldn't), then the factory should be passed in from application code.

An alternative would be to have another utility jar with nothing in it but a static session factory, and all hibernate-using jars use the same session factory provider jar (i.e. arrange it so that there's only one HibernateUtils, not one per jar).

If you have a "global" repository of any sort, a cache, a World object, anything like that, then you can put the session factory in there, and have all the jars use that one. This is still not a great solution, but it's better than one static factory per jar.


Top
 Profile  
 
 Post subject: Follow-up
PostPosted: Sat Apr 08, 2006 3:10 pm 
Newbie

Joined: Fri Oct 29, 2004 10:09 am
Posts: 1
YoavShapira wrote:
I think I got it... Instead of the reference documentation HibernateUtil I can have something like this:

In each library,
public class HibernateUtil {
private static SessionFactory sessionFactory;

public static void configure(Configuration configuration) {
sessionFactory = configuration.buildSessionFactory();
}

public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}

In the app that uses libraries:
public class Test {
public static void main(String[] args) {
Configuration configuration = new Configuration();
configuration.configure("lib1.cfg.xml");
configuration.configure("lib2.cfg.xml");
Library1.HibernateUtil.configure(configurtaion);
Library2.HibernateUtil.configure(configuration);
}
}

Is that right? I'll go test it out... Thanks again,

Yoav


Did you ever solve the problem? I have a similar one: I wrote a JAAS realm using hibernate. All works fine with the realm. Had to put the hibernate classes into the classpath so that tomcat can find them. From that point my web-app doesn't find the hibernate.cfg.xml anymore. Would be great if you could share your findings to have more than one hibernate.cfg.xml file.
Thanks, M


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.