I have three classes A, B, C as shown below. A has a field of type B, and B has a field of type array of C, called "cArray". B is mapped as an hibernate "component".
The component mapping for class B causes a NullPointerException in internal hibernate code, if either any value in cArray is null, or if cArray itself is null. If B is made an entity mapping, then there are no exceptions. (although B shouldn't be an entity).
The java code itself was written sometime ago, so it can't be changed.
My questions are
1) Is there anything wrong with the component mapping of B?
2) Does hibernate component mapping not allow null values in array fields of components, and the array field itself can't be null?
Appreciate any responses.
Exception:
Code:
java.lang.NullPointerException
at org.hibernate.engine.Collections.processReachableCollection(Collections.java:147)
at org.hibernate.event.def.FlushVisitor.processCollection(FlushVisitor.java:37)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
at org.hibernate.event.def.AbstractVisitor.processValues(AbstractVisitor.java:40)
at org.hibernate.event.def.AbstractVisitor.processComponent(AbstractVisitor.java:82)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:107)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:131)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:196)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at myPkg.HibernateService.doSave(TestService.java:55)
Java classesCode:
class A {
String aId; // the identifier for A
B b; // an instance of B
C c; // an instance of C
// some other attributes
}
class B {
C[] cArray; // an array of C instances, may contain null values, e.g c[1] could be null
// has NO other attributes
}
class C {
String cId; // the identifier for C
A parent; // reference back to its parent
// has some attributes
}
Simplified test code: Code:
A a = new A();
B b = new B();
C c = new C();
C c0 = new C();
C[] cArray = new C[]{c0, null} // adding a null for demonstration.
a.setB(b);
a.setC(c);
B.setCArray(cArray);
session.save(a);
session.flush();
session.commit();
Hibernate Mappings:
Mapping for class A: Code:
<class name='A">
<id name="aId" column="A_ID" type="string"/>
<one-to-one name="c"
class="C"
property-ref="parent"
cascade="all"
/>
<!-- Map field "A.b" as a component. This seems to cause NPE in hibernate code-->
<component name="b" class="B">
<!-- Map field "B.c"as an array -->
<array name="cArray" cascade="all">
<key column="FK_A_ID" />
<index column="VAL_INDEX" />
<one-to-many class="C" />
</array>
</component>
</class>
Mapping for Class C Code:
<class name="C">
<id name="cId" column="C_ID"/>
<many-to-one name="parent"
class="A"
column="FK_A_ID"
unique="true"/>
</class>
Database Schema:Code:
create TABLE_A(primary key (A_ID ), ....)
create TABLE_C(C_ID, VAL_INDEX, foreign key(FK_A_ID) REFERENCES A(A_ID) )