I want to use Hibernate in Eclipse as a plugin. We have a team of programmers and are planning on using several databases/schemas.
In order to minimize excess code between projects and to ensure proper session management, I have created my own plugin {HA} that does some basic stuff such as verifying the DB/Shchema exist, hbm2dll, creating/caching the SessionFactory, session/tx management, etc.
Several different plugins will use the {HA} plugin, call them {M1}, {M2},... {M1} passes a URL to its cfg.xml and mappings.jar (contains hbm.xml) files. These are resolved into File objects and added to the Configuration (all seems to work so far).
THE PROBLEM
However, when I create the session factory I get a NullPointerException (I assume it is because Hibernate cannot load the model class; see debug/trace info below).
Things I've Tried
1. Moving the model classes into my {HA} plugin works (i.e. objects are persisted). This shows there is nothing wrong with my code, but isn't very usefull, since I can't update {HA} every time I have a new {M?} to deploy and I don't necessarily need all of the models for all of my projects.
2. JARing {HA} and putting it into the LIB of {M1} also works, but now I cannot work with Hibernate classes (i.e. sessions) from {M1} in {M2} (link errors), since each has its own classloader and copy of the Hibernate Session class. This also means that every model plugin needs to have its own copy of the Hibernate jars and dependancies, which takes up too much space.
Is it a classloader issue??
All of my testing leads me to belive there must be a way that {M1} can share it's classloader with {HA} and the Hibernate Plugin (or vice-versa??). I'm not familiar with classloaders so I don't know how to make {M1}'s classloader available to the Hibernate plugin.
My code is available if you need it.
Hibernate version: 3.0
Mapping documents:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class
name="dbtest.TestPO"
dynamic-update="false"
dynamic-insert="false"
>
<id
name="id"
column="id"
type="java.lang.Long"
unsaved-value="-1"
>
<generator class="native">
</generator>
</id>
<property
name="timestamp"
type="java.util.Date"
update="true"
insert="true"
access="property"
column="timestamp"
/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():TEST POJO CODE IN A {M1} PLUGIN ACTIONCode:
//Note: See example HA code for details on ha.xxx() methods
// also: I removed try/catches to save space
TestPO o = new TestPO();
o.setTimestamp(new Date(System.currentTimeMillis()));
Serializable id = ha.saveObject(o);
Object get = ha.getObject(o.getClass(), o.getId());
ha.delete(o);
EXAMPLE HA METHODSCode:
public Serializable saveObject(Object obj) throws DatabaseException {
Session s = null;
Serializable ser = null;
try {
s = this.openSession();
ser = saveObject(obj, s);
} catch (Exception e) {
log.error("saveObject(o)", 321, "could not save: " + obj, e);
throw new DatabaseException(e);
} finally {
this.closeSession(s);
}
return ser;
}
public void saveOrUpdateObject(Object obj, Session s) throws DatabaseException {
Transaction tx = null;
try {
tx = s.beginTransaction();
s.saveOrUpdate(obj);
tx.commit();
} catch (Exception ex) {
rollback(tx);
log.error("saveOrUpdateObject(o,s)", 348, "could not save/update: " + obj, ex);
throw new DatabaseException(ex);
}
}
Full stack trace of any exception that occurs:Code:
09:37:14.291 ERROR dbtest.DbtestPlugin HibernateAdapter.createSessionFactory():747 java.lang.NullPointerException, Error Creating session factory: dbtest
java.lang.NullPointerException
at org.hibernate.mapping.PersistentClass.getMappedClass(PersistentClass.java:87)
at org.hibernate.tuple.PropertyFactory.getGetter(PropertyFactory.java:148)
at org.hibernate.tuple.PropertyFactory.buildIdentifierProperty(PropertyFactory.java:41)
at org.hibernate.tuple.EntityMetamodel.<init>(EntityMetamodel.java:104)
at org.hibernate.persister.entity.BasicEntityPersister.<init>(BasicEntityPersister.java:398)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:104)
at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:55)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:199)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1043)
at com.dynetics.rdf.hibernate.HibernateAdapter.createSessionFactory(HibernateAdapter.java:898)
at com.dynetics.rdf.hibernate.HibernateAdapter.<init>(HibernateAdapter.java:816)
at com.dynetics.rdf.hibernate.HibernateAdapter.getHibernateAdapter(HibernateAdapter.java:264)
at com.dynetics.rdf.hibernate.HibernateAdapter.getHibernateAdapter(HibernateAdapter.java:165)
at dbtest.DbtestPlugin.run(DbtestPlugin.java:108)
at java.lang.Thread.run(Thread.java:536)
Name and version of the database you are using:postgreSQL 8.0-311
Debug level Hibernate log excerpt:Code:
09:37:11.314 DEBUG dbtest.DbtestPlugin HibernateAdapter.createSessionFactory():740, Adding mappings jar: dbtest w:\vcs1\dbtest\gen\dbtest.dbmappings.jar
09:37:11,314 INFO Configuration:477 - Searching for mapping documents in jar: dbtest.dbmappings.jar
09:37:11,314 INFO Configuration:494 - Found mapping documents in jar: dbtest/TestPO.hbm.xml
09:37:11,314 DEBUG DTDEntityResolver:42 - trying to locate http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd in classpath under org/hibernate/
09:37:11,324 DEBUG DTDEntityResolver:49 - http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd not found in classpath
09:37:12,196 INFO HbmBinder:256 - Mapping class: dbtest.TestPO -> TestPO
09:37:12,216 DEBUG HbmBinder:1086 - Mapped property: id -> id
09:37:12,236 DEBUG HbmBinder:1086 - Mapped property: timestamp -> timestamp
09:37:12.246 DEBUG dbtest.DbtestPlugin HibernateAdapter.createSessionFactory():744, Creating session factory: dbtest
09:37:12,246 DEBUG Configuration:1035 - Preparing to build session factory with filters : {}
09:37:12,246 INFO Configuration:844 - processing extends queue
09:37:12,246 INFO Configuration:848 - processing collection mappings
09:37:12,246 INFO Configuration:857 - processing association property references
09:37:12,246 INFO Configuration:884 - processing foreign key constraints
09:37:12,366 INFO Dialect:89 - Using dialect: org.hibernate.dialect.PostgreSQLDialect
09:37:12,376 DEBUG SQLExceptionConverterFactory:52 - Using dialect defined converter
09:37:12,376 INFO SettingsFactory:81 - Default schema: dbtest
09:37:12,386 INFO SettingsFactory:90 - Default batch fetch size: 1
09:37:12,386 INFO SettingsFactory:94 - Generate SQL with comments: disabled
09:37:12,386 INFO SettingsFactory:98 - Order SQL updates by primary key: disabled
09:37:12,386 INFO SettingsFactory:273 - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
09:37:12,396 INFO ASTQueryTranslatorFactory:21 - Using ASTQueryTranslatorFactory
09:37:12,396 INFO SettingsFactory:106 - Query language substitutions: {}
09:37:12,406 INFO C3P0ConnectionProvider:50 - C3P0 using driver: org.postgresql.Driver at URL: jdbc:postgresql://localhost:5432/rdf
09:37:12,406 INFO C3P0ConnectionProvider:51 - Connection properties: {user=gmpm, password=****}
09:37:12,406 INFO C3P0ConnectionProvider:54 - autocommit mode: false
09:37:13,138 INFO SettingsFactory:148 - JDBC batch size: 15
09:37:13,138 INFO SettingsFactory:151 - JDBC batch updates for versioned data: disabled
09:37:13,138 INFO SettingsFactory:156 - Scrollable result sets: enabled
09:37:13,138 DEBUG SettingsFactory:160 - Wrap result sets: disabled
09:37:13,138 INFO SettingsFactory:164 - JDBC3 getGeneratedKeys(): disabled
09:37:13,138 INFO TransactionFactoryFactory:31 - Using default transaction strategy (direct JDBC transactions)
09:37:13,148 INFO TransactionManagerLookupFactory:33 - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
09:37:13,158 INFO SettingsFactory:176 - Automatic flush during beforeCompletion(): disabled
09:37:13,158 INFO SettingsFactory:179 - Automatic session close at end of transaction: disabled
09:37:13,158 INFO SettingsFactory:260 - Cache provider: org.hibernate.cache.EhCacheProvider
09:37:13,178 INFO SettingsFactory:187 - Second-level cache: enabled
09:37:13,178 INFO SettingsFactory:192 - Optimize cache for minimal puts: disabled
09:37:13,178 INFO SettingsFactory:199 - Structured second-level cache entries: enabled
09:37:13,288 INFO SettingsFactory:203 - Query cache: disabled
09:37:13,288 INFO SettingsFactory:210 - Echoing all SQL to stdout
09:37:13,288 INFO SettingsFactory:214 - Statistics: enabled
09:37:13,288 INFO SettingsFactory:218 - Deleted entity synthetic identifier rollback: disabled
Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@1304043 [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@fa70a4 [ acquireIncrement -> 1, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, idleConnectionTestPeriod -> 0, initialPoolSize -> 5, maxIdleTime -> 1800, maxPoolSize -> 20, maxStatements -> 50, maxStatementsPerConnection -> 0, minPoolSize -> 5, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@1ca209e [ description -> null, driverClass -> null, factoryClassLocation -> null, jdbcUrl -> jdbc:postgresql://localhost:5432/rdf, properties -> {user=******, password=******} ] , preferredTestQuery -> null, propertyCycle -> 300, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, usesTraditionalReflectiveProxies -> false ] , factoryClassLocation -> null, numHelperThreads -> 3, poolOwnerIdentityToken -> 1304043 ]
09:37:13,679 INFO SettingsFactory:232 - Default entity-mode: pojo
09:37:14,020 INFO SessionFactoryImpl:140 - building session factory
09:37:14,020 DEBUG SessionFactoryImpl:149 - Session factory constructed with filter configurations : {}
09:37:14,020 DEBUG SessionFactoryImpl:152 - instantiating session factory with properties: {java.vendor=Sun Microsystems Inc., osgi.bundles.defaultStartLevel=4, org.osgi.supports.framework.extension=true, hibernate.connection.url=jdbc:postgresql://localhost:5432/rdf, osgi.framework.beginningstartlevel=1, os.name=Windows XP, sun.boot.class.path=C:\Programs\j2sdk1.4.1_01\jre\lib\rt.jar;C:\Programs\j2sdk1.4.1_01\jre\lib\i18n.jar;C:\Programs\j2sdk1.4.1_01\jre\lib\sunrsasign.jar;C:\Programs\j2sdk1.4.1_01\jre\lib\jsse.jar;C:\Programs\j2sdk1.4.1_01\jre\lib\jce.jar;C:\Programs\j2sdk1.4.1_01\jre\lib\charsets.jar;C:\Programs\j2sdk1.4.1_01\jre\classes, osgi.ws=win32, hibernate.c3p0.max_size=20, sun.java2d.fontpath=, java.vm.specification.vendor=Sun Microsystems Inc., hibernate.generate_statistics=true, java.runtime.version=1.4.1_01-b01, hibernate.c3p0.min_size=5, osgi.instance.area=file:/w:/runtime-workspace/, user.name=ironside, org.osgi.framework.system.packages=javax.accessibility,javax.crypto,javax.crypto.interfaces,javax.crypto.spec,javax.imageio,javax.imageio.event,javax.imageio.metadata,javax.imageio.plugins.jpeg,javax.imageio.spi,javax.imageio.stream,javax.naming,javax.naming.directory,javax.naming.event,javax.naming.ldap,javax.naming.spi,javax.net,javax.net.ssl,javax.print,javax.print.attribute,javax.print.attribute.standard,javax.print.event,javax.rmi,javax.rmi.CORBA,javax.security.auth,javax.security.auth.callback,javax.security.auth.kerberos,javax.security.auth.login,javax.security.auth.spi,javax.security.auth.x500,javax.security.cert,javax.sound.midi,javax.sound.midi.spi,javax.sound.sampled,javax.sound.sampled.spi,javax.sql,javax.swing,javax.swing.border,javax.swing.colorchooser,javax.swing.event,javax.swing.filechooser,javax.swing.plaf,javax.swing.plaf.basic,javax.swing.plaf.metal,javax.swing.plaf.multi,javax.swing.table,javax.swing.text,javax.swing.text.html,javax.swing.text.html.parser,javax.swing.text.rtf,javax.swing.tree,javax.swing.undo,javax.transaction,javax.transaction.xa,javax.xml.parsers,javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.sax,javax.xml.transform.stream,org.ietf.jgss,org.omg.CORBA,org.omg.CORBA_2_3,org.omg.CORBA_2_3.portable,org.omg.CORBA.DynAnyPackage,org.omg.CORBA.ORBPackage,org.omg.CORBA.portable,org.omg.CORBA.TypeCodePackage,org.omg.CosNaming,org.omg.CosNaming.NamingContextExtPackage,org.omg.CosNaming.NamingContextPackage,org.omg.Dynamic,org.omg.DynamicAny,org.omg.DynamicAny.DynAnyFactoryPackage,org.omg.DynamicAny.DynAnyPackage,org.omg.IOP,org.omg.IOP.CodecFactoryPackage,org.omg.IOP.CodecPackage,org.omg.Messaging,org.omg.PortableInterceptor,org.omg.PortableInterceptor.ORBInitInfoPackage,org.omg.PortableServer,org.omg.PortableServer.CurrentPackage,org.omg.PortableServer.POAManagerPackage,org.omg.PortableServer.POAPackage,org.omg.PortableServer.portable,org.omg.PortableServer.ServantLocatorPackage,org.omg.SendingContext,org.omg.stub.java.rmi,org.w3c.dom,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers, hibernate.session_factory_name=testdb.sf, org.osgi.framework.language=en, hibernate.c3p0.timeout=1800, user.language=en, org.osgi.framework.processor=x86, osgi.syspath=c:\Program Files\eclipse3.1\eclipse\plugins, sun.boot.library.path=C:\Programs\j2sdk1.4.1_01\jre\bin, osgi.manifest.cache=w:\vcs1\.metadata\.plugins\org.eclipse.pde.core\VCS\org.eclipse.osgi\manifests, org.osgi.framework.bootdelegation=*, java.version=1.4.1_01, org.osgi.framework.os.name=WindowsXP, version=2.2.D11, user.timezone=America/Chicago, sun.arch.data.model=32, osgi.bundles=reference:file:w:/vcs1/com.dynetics.logger/,reference:file:w:/vcs1/com.dynetics.rdf.hibernate/,reference:file:w:/vcs1/com.dynetics.vcs/,reference:file:w:/vcs1/dbtest/,reference:file:C:/Program Files/eclipse3.1/eclipse/plugins/org.eclipse.core.commands_3.1.0.jar/,reference:file:C:/Program Files/eclipse3.1/eclipse/plugins/org.eclipse.core.expressions_3.1.0.jar/,reference:file:C:/Program Files/eclipse3.1/eclipse/plugins/org.eclipse.core.runtime_3.1.0.jar/@2:start,reference:file:C:/Program Files/eclipse3.1/eclipse/plugins/org.eclipse.help_3.1.0.jar/,reference:file:C:/Program Files/eclipse3.1/eclipse/plugins/org.eclipse.jface_3.1.0.jar/,reference:file:C:/Program Files/eclipse3.1/eclipse/plugins/org.eclipse.swt_3.1.0.jar/,reference:file:C:/Program Files/eclipse3.1/eclipse/plugins/org.eclipse.swt.win32.win32.x86_3.1.0.jar/,reference:file:C:/Program Files/eclipse3.1/eclipse/plugins/org.eclipse.ui_3.1.0.jar/,reference:file:C:/Program Files/eclipse3.1/eclipse/plugins/org.eclipse.ui.forms_3.1.0.jar/,reference:file:C:/Program Files/eclipse3.1/eclipse/plugins/org.eclipse.ui.intro_3.1.0.jar/,reference:file:C:/Program Files/eclipse3.1/eclipse/plugins/org.eclipse.ui.workbench_3.1.0.jar/, java.endorsed.dirs=C:\Programs\j2sdk1.4.1_01\jre\lib\endorsed, sun.cpu.isalist=pentium i486 i386, eclipse.application=com.dynetics.vcs.VCSApplicationID, file.encoding.pkg=sun.io, org.osgi.framework.vendor=Eclipse, file.separator=\, java.specification.name=Java Platform API Specification, osgi.checkConfiguration=true, hibernate.cglib.use_reflection_optimizer=true, java.class.version=48.0, user.country=US, osgi.configuration.cascaded=false, java.home=C:\Programs\j2sdk1.4.1_01\jre, osgi.os=win32, eclipse.commands=-launcher
c:\Program Files\eclipse3.1\eclipse\eclipse
-name
Eclipse
-showsplash
600
-product
com.dynetics.vcs.VCSProductID
-data
w:\runtime-workspace
-configuration
file:w:/vcs1/.metadata/.plugins/org.eclipse.pde.core/VCS/
-dev
file:w:/vcs1/.metadata/.plugins/org.eclipse.pde.core/VCS/dev.properties
-pdelaunch
-os
win32
-ws
win32
-arch
x86
, java.vm.info=mixed mode, osgi.splashLocation=w:\vcs1\com.dynetics.vcs\splash.bmp, os.version=5.1, osgi.arch=x86, path.separator=;, java.vm.version=1.4.1_01-b01, hibernate.connection.password=gmpm, java.util.prefs.PreferencesFactory=java.util.prefs.WindowsPreferencesFactory, user.variant=, vendor-url=http://xml.apache.org/xalan-j, osgi.framework.shape=jar, java.awt.printerjob=sun.awt.windows.WPrinterJob, vendor=Apache Software Foundation, sun.io.unicode.encoding=UnicodeLittle, org.osgi.framework.version=1.3.0, awt.toolkit=sun.awt.windows.WToolkit, hibernate.connection.username=gmpm, osgi.dev=file:w:/vcs1/.metadata/.plugins/org.eclipse.pde.core/VCS/dev.properties, osgi.install.area=file:/c:/Program Files/eclipse3.1/eclipse/, osgi.framework=file:/C:/Program Files/eclipse3.1/eclipse/plugins/org.eclipse.osgi_3.1.0.jar, user.home=C:\Documents and Settings\eric, osgi.bundlestore=w:\vcs1\.metadata\.plugins\org.eclipse.pde.core\VCS\org.eclipse.osgi\bundles, osgi.splashPath=file:w:/vcs1/com.dynetics.vcs/, java.specification.vendor=Sun Microsystems Inc., osgi.nl=en_US, org.xml.sax.driver=org.apache.crimson.parser.XMLReaderImpl, hibernate.hbm2ddl.auto=update, java.library.path=C:\Programs\j2sdk1.4.1_01\bin;.;C:\WINDOWS\system32;C:\WINDOWS;C:\Programs\j2sdk1.4.1_01\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\Common Files\Adaptec Shared\System;C:\PROGRA~1\IBM\IMNNQ;C:\Program Files\SQLLIB\BIN;C:\Program Files\SQLLIB\FUNCTION;C:\Program Files\SQLLIB\SAMPLES\REPL;C:\Program Files\SQLLIB\HELP;C:\Programs\j2sdk1.4.1_01\bin;c:\programs\wtk104\bin\;C:\Program Files\eclipse-SDK-3.0.1\hyades.rac.nt_3.2.0_20041221_1637\bin;C:\Program Files\Common Files\Technology Builders, Inc;C:\Program Files\eclipse-SDK-3.1-win32\tptpdc\win_ia32\bin, java.vendor.url=http://java.sun.com/, eclipse.startTime=1124203022093, org.osgi.framework.os.version=5.1, hibernate.connection.driver_class=org.postgresql.Driver, java.vm.vendor=Sun Microsystems Inc., hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect, java.runtime.name=Java(TM) 2 Runtime Environment, Standard Edition, java.class.path=c:\Program Files\eclipse3.1\eclipse\startup.jar, java.vm.specification.name=Java Virtual Machine Specification, java.vm.specification.version=1.0, hibernate.schema=dbtest, sun.cpu.endian=little, sun.os.patch.level=Service Pack 2, java.io.tmpdir=C:\DOCUME~1\eric\LOCALS~1\Temp\, java.vendor.url.bug=http://java.sun.com/cgi-bin/bugreport.cgi, hibernate.default_schema=dbtest, eclipse.product=com.dynetics.vcs.VCSProductID, os.arch=x86, java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment, java.ext.dirs=C:\Programs\j2sdk1.4.1_01\jre\lib\ext, user.dir=w:\vcs1, line.separator=
, java.vm.name=Java HotSpot(TM) Client VM, file.encoding=Cp1252, osgi.framework.version=3.0.0, java.specification.version=1.4, org.osgi.framework.executionenvironment=J2SE-1.4, hibernate.c3p0.max_statements=50, hibernate.show_sql=true, osgi.logfile=w:\runtime-workspace\.metadata\.log, osgi.configuration.area=file:/w:/vcs1/.metadata/.plugins/org.eclipse.pde.core/VCS/}
09:37:14,090 WARN Configurator:126 - No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath: bundleresource://26/ehcache-failsafe.xml
09:37:14.291 ERROR dbtest.DbtestPlugin HibernateAdapter.createSessionFactory():747 java.lang.NullPointerException, Error Creating session factory: dbtest
java.lang.NullPointerException
at org.hibernate.mapping.PersistentClass.getMappedClass(PersistentClass.java:87)
at org.hibernate.tuple.PropertyFactory.getGetter(PropertyFactory.java:148)
at org.hibernate.tuple.PropertyFactory.buildIdentifierProperty(PropertyFactory.java:41)
at org.hibernate.tuple.EntityMetamodel.<init>(EntityMetamodel.java:104)
at org.hibernate.persister.entity.BasicEntityPersister.<init>(BasicEntityPersister.java:398)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:104)
at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:55)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:199)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1043)
at com.dynetics.rdf.hibernate.HibernateAdapter.createSessionFactory(HibernateAdapter.java:898)
at com.dynetics.rdf.hibernate.HibernateAdapter.<init>(HibernateAdapter.java:816)
at com.dynetics.rdf.hibernate.HibernateAdapter.getHibernateAdapter(HibernateAdapter.java:264)
at com.dynetics.rdf.hibernate.HibernateAdapter.getHibernateAdapter(HibernateAdapter.java:165)
at dbtest.DbtestPlugin.run(DbtestPlugin.java:108)
at java.lang.Thread.run(Thread.java:536)