I'm getting a NullPointerException when PersistentIndexedElementHolder.readFrom passes a null CollectionPersister.getElementNodeName() return value to org.dom4j.Element.addElement() when trying to get the XML view of the object.
This comes from the mapping document not defining a node attribute for the list/element. While this is a human error on my part, it took quite awhile to hunt down the problem. I think that org.hibernate.collection.PersistentElementHolder.readFrom(), or its caller, should throw a HibernateException that gives some information about the element that doesn't have the node defined.
I looked into writting this, but was unable to find the information about the Hibernate entity at the PersistentElementHolder.readFrom level. Any suggestions for what the behavoir should be in this error case?
Hibernate version:
Hibernate3 HEAD
Mapping documents:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.dom4j">
<class name="Building" lazy="false" node="building">
<id name="id" node="@id" type="long">
<generator class="increment"/>
</id>
<list name="officeList" node="offices" cascade="all">
<key column="building_id" />
<index column="x" />
<!-- Correct -->
<!--
<element column="desc" type="string" not-null="true" node="desc"/>
-->
<!-- Incorrect, node attribute required -->
<element column="desc" type="string" not-null="true"/>
</list>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
org.hibernate.test.dom4j.Dom4jElementTest
public void testDom4jNullElementNodeName() throws Exception {
Session s = openSession();
Transaction t = s.beginTransaction();
Building building = new Building();
building.getOfficeList().add("Office 1");
building.getOfficeList().add("Office 2");
s.save(building);
t.commit();
s.close();
s = openSession();
Session dom4jSession = s.getSession( EntityMode.DOM4J );
t = s.beginTransaction();
Element element = (Element) dom4jSession.get(Building.class,
building.getId());
print(element);
s.delete(building);
t.commit();
s.close();
}
public static void print(Element elt) throws Exception {
OutputFormat outformat = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter( System.out, outformat );
writer.write( elt );
writer.flush();
}
protected String[] getMappings() {
return new String[] { "dom4j/Building.hbm.xml" };
}
Full stack trace of any exception that occurs:Code:
Testcase: testDom4jNullElementNodeName took 2.375 sec
Caused an ERROR
null
java.lang.NullPointerException
at org.d.addElemenom4j.tree.AbstractElementt(AbstractElement.java:825)
at org.hibernate.collection.PersistentIndexedElementHolder.readFrom(PersistentIndexedElementHolder.java:149)
at org.hibernate.loader.Loader.readCollectionElement(Loader.java:942)
at org.hibernate.loader.Loader.readCollectionElements(Loader.java:619)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:563)
at org.hibernate.loader.Loader.doQuery(Loader.java:666)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:221)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1787)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:500)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1446)
at org.hibernate.type.CollectionType.getCollection(CollectionType.java:488)
at org.hibernate.type.CollectionType.resolveKey(CollectionType.java:332)
at org.hibernate.type.CollectionType.resolve(CollectionType.java:326)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:111)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:792)
at org.hibernate.loader.Loader.doQuery(Loader.java:690)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:221)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1695)
at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:117)
at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:102)
at org.hibernate.persister.entity.BasicEntityPersister.load(BasicEntityPersister.java:2476)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:358)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:339)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:116)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:154)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:82)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:636)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:629)
at org.hibernate.test.dom4j.Dom4jElementTest.testDom4jNullElementNodeName(Dom4jElementTest.java:43)
at org.hibernate.test.TestCase.runTest(TestCase.java:129)
Contents of testout/TEST-org.hibernate.test.dom4j.Dom4jElementTest.txtCode:
Testsuite: org.hibernate.test.dom4j.Dom4jElementTest
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 2.703 sec
------------- Standard Output ---------------
11:13:15,693 INFO Environment:464 - Hibernate 3.1 beta 1
11:13:15,709 INFO Environment:482 - loaded properties from resource hibernate.properties: {hibernate.connection.driver_class=org.hsqldb.jdbcDriver, hibernate.cglib.use_reflection_optimizer=true, hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider, hibernate.max_fetch_depth=1, hibernate.dialect=org.hibernate.dialect.HSQLDialect, hibernate.jdbc.use_streams_for_binary=true, hibernate.query.substitutions=true 1, false 0, yes 'Y', no 'N', hibernate.proxool.pool_alias=pool1, hibernate.connection.username=sa, hibernate.cache.region_prefix=hibernate.test, hibernate.connection.url=jdbc:hsqldb:., hibernate.connection.password=****, hibernate.jdbc.batch_versioned_data=true, hibernate.connection.pool_size=1}
11:13:15,709 INFO Environment:509 - using java.io streams to persist binary types
11:13:15,709 INFO Environment:510 - using CGLIB reflection optimizer
11:13:15,709 INFO Environment:540 - using JDK 1.4 java.sql.Timestamp handling
11:13:15,849 INFO Configuration:408 - Reading mappings from resource: org/hibernate/test/dom4j/Building.hbm.xml
11:13:16,209 INFO HbmBinder:268 - Mapping class: org.hibernate.test.dom4j.Building -> Building
11:13:16,240 INFO HbmBinder:1242 - Mapping collection: org.hibernate.test.dom4j.Building.officeList -> officeList
11:13:16,302 INFO Dialect:93 - Using dialect: org.hibernate.dialect.HSQLDialect
11:13:16,396 INFO Configuration:851 - processing extends queue
11:13:16,396 INFO Configuration:855 - processing collection mappings
11:13:16,412 INFO Configuration:864 - processing association property references
11:13:16,412 INFO Configuration:893 - processing foreign key constraints
11:13:16,459 INFO DriverManagerConnectionProvider:41 - Using Hibernate built-in connection pool (not for production use!)
11:13:16,459 INFO DriverManagerConnectionProvider:42 - Hibernate connection pool size: 1
11:13:16,459 INFO DriverManagerConnectionProvider:45 - autocommit mode: false
11:13:16,474 INFO DriverManagerConnectionProvider:80 - using driver: org.hsqldb.jdbcDriver at URL: jdbc:hsqldb:.
11:13:16,474 INFO DriverManagerConnectionProvider:86 - connection properties: {user=sa, password=****}
11:13:16,865 INFO SettingsFactory:77 - RDBMS: HSQL Database Engine, version: 1.7.3
11:13:16,865 INFO SettingsFactory:78 - JDBC driver: HSQL Database Engine Driver, version: 1.7.3
11:13:16,880 INFO Dialect:93 - Using dialect: org.hibernate.dialect.HSQLDialect
11:13:16,896 INFO TransactionFactoryFactory:31 - Using default transaction strategy (direct JDBC transactions)
11:13:16,896 INFO TransactionManagerLookupFactory:33 - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
11:13:16,896 INFO SettingsFactory:125 - Automatic flush during beforeCompletion(): disabled
11:13:16,896 INFO SettingsFactory:129 - Automatic session close at end of transaction: disabled
11:13:16,896 INFO SettingsFactory:136 - JDBC batch size: 15
11:13:16,896 INFO SettingsFactory:139 - JDBC batch updates for versioned data: enabled
11:13:16,912 INFO SettingsFactory:144 - Scrollable result sets: enabled
11:13:16,912 INFO SettingsFactory:152 - JDBC3 getGeneratedKeys(): disabled
11:13:16,912 INFO SettingsFactory:160 - Connection release mode: null
11:13:16,912 INFO SettingsFactory:184 - Maximum outer join fetch depth: 1
11:13:16,912 INFO SettingsFactory:187 - Default batch fetch size: 1
11:13:16,912 INFO SettingsFactory:191 - Generate SQL with comments: disabled
11:13:16,912 INFO SettingsFactory:195 - Order SQL updates by primary key: disabled
11:13:16,912 INFO SettingsFactory:334 - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
11:13:16,912 INFO ASTQueryTranslatorFactory:21 - Using ASTQueryTranslatorFactory
11:13:16,912 INFO SettingsFactory:203 - Query language substitutions: {no='N', true=1, yes='Y', false=0}
11:13:16,927 INFO SettingsFactory:209 - Second-level cache: enabled
11:13:16,927 INFO SettingsFactory:213 - Query cache: disabled
11:13:16,927 INFO SettingsFactory:321 - Cache provider: org.hibernate.cache.HashtableCacheProvider
11:13:16,927 INFO SettingsFactory:228 - Optimize cache for minimal puts: disabled
11:13:16,927 INFO SettingsFactory:233 - Cache region prefix: hibernate.test
11:13:16,927 INFO SettingsFactory:237 - Structured second-level cache entries: disabled
11:13:16,943 INFO SettingsFactory:261 - Statistics: disabled
11:13:16,943 INFO SettingsFactory:265 - Deleted entity synthetic identifier rollback: disabled
11:13:16,943 INFO SettingsFactory:279 - Default entity-mode: pojo
11:13:17,130 INFO SessionFactoryImpl:156 - building session factory
11:13:17,537 INFO SessionFactoryObjectFactory:82 - Not binding factory to JNDI, no JNDI name configured
11:13:17,552 INFO Dialect:93 - Using dialect: org.hibernate.dialect.HSQLDialect
11:13:17,552 INFO Configuration:851 - processing extends queue
11:13:17,552 INFO Configuration:855 - processing collection mappings
11:13:17,552 INFO Configuration:864 - processing association property references
11:13:17,552 INFO Configuration:893 - processing foreign key constraints
11:13:17,568 INFO Configuration:851 - processing extends queue
11:13:17,568 INFO Configuration:855 - processing collection mappings
11:13:17,568 INFO Configuration:864 - processing association property references
11:13:17,568 INFO Configuration:893 - processing foreign key constraints
11:13:17,568 INFO SchemaExport:113 - Running hbm2ddl schema export
11:13:17,568 INFO SchemaExport:129 - exporting generated schema to database
11:13:17,568 INFO DriverManagerConnectionProvider:41 - Using Hibernate built-in connection pool (not for production use!)
11:13:17,568 INFO DriverManagerConnectionProvider:42 - Hibernate connection pool size: 1
11:13:17,568 INFO DriverManagerConnectionProvider:45 - autocommit mode: false
11:13:17,568 INFO DriverManagerConnectionProvider:80 - using driver: org.hsqldb.jdbcDriver at URL: jdbc:hsqldb:.
11:13:17,568 INFO DriverManagerConnectionProvider:86 - connection properties: {user=sa, password=****}
11:13:17,568 DEBUG SchemaExport:143 - alter table officeList drop constraint FKC3E5A57A6D9E7AC6
11:13:17,568 DEBUG SchemaExport:149 - Unsuccessful: alter table officeList drop constraint FKC3E5A57A6D9E7AC6
11:13:17,568 DEBUG SchemaExport:150 - Table not found: OFFICELIST in statement [alter table officeList]
11:13:17,568 DEBUG SchemaExport:143 - drop table Building if exists
11:13:17,568 DEBUG SchemaExport:143 - drop table officeList if exists
11:13:17,568 DEBUG SchemaExport:161 - create table Building (
id bigint not null,
primary key (id)
)
11:13:17,584 DEBUG SchemaExport:161 - create table officeList (
building_id bigint not null,
desc varchar(255) not null,
x integer not null,
primary key (building_id, x)
)
11:13:17,584 DEBUG SchemaExport:161 - alter table officeList
add constraint FKC3E5A57A6D9E7AC6
foreign key (building_id)
references Building
11:13:17,584 INFO SchemaExport:173 - schema export complete
11:13:17,584 INFO DriverManagerConnectionProvider:147 - cleaning up connection pool: jdbc:hsqldb:.
11:13:17,584 INFO Dialect:93 - Using dialect: org.hibernate.dialect.HSQLDialect
11:13:17,584 INFO Configuration:851 - processing extends queue
11:13:17,584 INFO Configuration:855 - processing collection mappings
11:13:17,599 INFO Configuration:864 - processing association property references
11:13:17,599 INFO Configuration:893 - processing foreign key constraints
11:13:17,599 INFO Configuration:851 - processing extends queue
11:13:17,599 INFO Configuration:855 - processing collection mappings
11:13:17,599 INFO Configuration:864 - processing association property references
11:13:17,599 INFO DriverManagerConnectionProvider:147 - cleaning up connection pool: jdbc:hsqldb:.
11:13:17,599 INFO Configuration:893 - processing foreign key constraints
11:13:17,599 INFO SessionFactoryImpl:411 - Checking 0 named queries
11:13:17,662 DEBUG SQL:85 - select max(id) from Building
11:13:17,802 DEBUG SQL:324 - insert into Building (id) values (?)
11:13:17,802 DEBUG LongType:59 - binding '1' to parameter: 1
11:13:17,818 DEBUG SQL:324 - insert into officeList (building_id, x, desc) values (?, ?, ?)
11:13:17,818 DEBUG LongType:59 - binding '1' to parameter: 1
11:13:17,818 DEBUG IntegerType:59 - binding '0' to parameter: 2
11:13:17,834 DEBUG StringType:59 - binding 'Office 1' to parameter: 3
11:13:17,834 DEBUG SQL:324 - insert into officeList (building_id, x, desc) values (?, ?, ?)
11:13:17,834 DEBUG LongType:59 - binding '1' to parameter: 1
11:13:17,834 DEBUG IntegerType:59 - binding '1' to parameter: 2
11:13:17,834 DEBUG StringType:59 - binding 'Office 2' to parameter: 3
11:13:17,834 DEBUG SQL:324 - select building0_.id as id0_ from Building building0_ where building0_.id=?
11:13:17,849 DEBUG LongType:59 - binding '1' to parameter: 1
11:13:17,865 DEBUG SQL:324 - select officelist0_.building_id as building1_0_, officelist0_.desc as desc0_, officelist0_.x as x0_ from officeList officelist0_ where officelist0_.building_id=?
11:13:17,865 DEBUG LongType:59 - binding '1' to parameter: 1
11:13:17,865 DEBUG LongType:86 - returning '1' as column: building1_0_
11:13:17,865 DEBUG StringType:86 - returning 'Office 1' as column: desc0_
persister: BasicCollectionPersister(org.hibernate.test.dom4j.Building.officeList)
Adding element:null
Adding element:offices
indexNode:null
object:Office 1
11:13:17,865 INFO SessionFactoryImpl:831 - closing
11:13:17,880 INFO DriverManagerConnectionProvider:147 - cleaning up connection pool: jdbc:hsqldb:.
11:13:17,880 INFO SchemaExport:113 - Running hbm2ddl schema export
11:13:17,880 INFO SchemaExport:129 - exporting generated schema to database
11:13:17,880 INFO DriverManagerConnectionProvider:41 - Using Hibernate built-in connection pool (not for production use!)
11:13:17,880 INFO DriverManagerConnectionProvider:42 - Hibernate connection pool size: 1
11:13:17,880 INFO DriverManagerConnectionProvider:45 - autocommit mode: false
11:13:17,880 INFO DriverManagerConnectionProvider:80 - using driver: org.hsqldb.jdbcDriver at URL: jdbc:hsqldb:.
11:13:17,880 INFO DriverManagerConnectionProvider:86 - connection properties: {user=sa, password=****}
11:13:17,880 DEBUG SchemaExport:143 - alter table officeList drop constraint FKC3E5A57A6D9E7AC6
11:13:17,880 DEBUG SchemaExport:143 - drop table Building if exists
11:13:17,880 DEBUG SchemaExport:143 - drop table officeList if exists
11:13:17,880 INFO SchemaExport:173 - schema export complete
11:13:17,880 INFO DriverManagerConnectionProvider:147 - cleaning up connection pool: jdbc:hsqldb:.
------------- ---------------- ---------------
Testcase: testDom4jNullElementNodeName took 2.375 sec
Caused an ERROR
null
java.lang.NullPointerException
at org.dom4j.tree.AbstractElement.addElement(AbstractElement.java:825)
at org.hibernate.collection.PersistentIndexedElementHolder.readFrom(PersistentIndexedElementHolder.java:149)
at org.hibernate.loader.Loader.readCollectionElement(Loader.java:942)
at org.hibernate.loader.Loader.readCollectionElements(Loader.java:619)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:563)
at org.hibernate.loader.Loader.doQuery(Loader.java:666)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:221)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1787)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:500)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1446)
at org.hibernate.type.CollectionType.getCollection(CollectionType.java:488)
at org.hibernate.type.CollectionType.resolveKey(CollectionType.java:332)
at org.hibernate.type.CollectionType.resolve(CollectionType.java:326)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:111)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:792)
at org.hibernate.loader.Loader.doQuery(Loader.java:690)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:221)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1695)
at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:117)
at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:102)
at org.hibernate.persister.entity.BasicEntityPersister.load(BasicEntityPersister.java:2476)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:358)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:339)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:116)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:154)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:82)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:636)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:629)
at org.hibernate.test.dom4j.Dom4jElementTest.testDom4jNullElementNodeName(Dom4jElementTest.java:43)
at org.hibernate.test.TestCase.runTest(TestCase.java:129)