Hi
I have a not so peculiar requirement.
But I couldnt figure out any way to map this relationship in *.hbm.xml files.
Here is the problem.
I have 3 tables.
TABLE 1
CREATE TABLE entity_one (
oid VARCHAR2(50) NOT NULL,
field1 VARCHAR2(50) NOT NULL,
field2 VARCHAR2(50),
PRIMARY KEY (oid)
);
TABLE 2
CREATE TABLE entity_two (
oid VARCHAR2(50) NOT NULL,
field1 VARCHAR2(50) NOT NULL,
field2 VARCHAR2(50),
PRIMARY KEY (oid)
);
TABLE 3
CREATE TABLE entity_extn (
oid VARCHAR2(50) NOT NULL,
entity_oid VARCHAR2(50) NOT NULL,
extn_name VARCHAR2(50) NOT NULL,
extn_value VARCHAR2(255),
PRIMARY KEY (oid),
CONSTRAINT UN_entity_extn_1 UNIQUE (entity_oid, extn_name)
);
entity_one and entity_two are two independent tables. (no FK relationships between them).
entity_extn is sort of extension table for both the tables.
It can store extra fields for both the tables as name-value pairs.
So the entity_extn.entity_oid can be sometimes entity_one.oid or entity_two.oid.
There is no hard reference defined between extn table and base tables at the database level.
(Because its not possible.......)
I have only soft reference checks (in my java code).
My entity_extn.hbm.xml looks as follows.
<class name="com.pojos.EntityExtn" table="ENTITY_EXTN">
<id name="oid" type="java.lang.String">
<column name="OID" scale="50" precision="0" not-null="true" unique="true" sql-type="VARCHAR2" />
<generator class="uuid.hex" />
</id>
<property name="entityOid" type="java.lang.String">
<column name="ENTITY_OID" scale="50" precision="0" not-null="true" sql-type="VARCHAR2" />
</property>
<property name="extnName" type="java.lang.String">
<column name="EXTN_NAME" scale="50" precision="0" not-null="true" sql-type="VARCHAR2" />
</property>
<property name="extnValue" type="java.lang.String">
<column name="EXTN_VALUE" scale="255" precision="0" not-null="false" sql-type="VARCHAR2" />
</property>
</class>
---------------------------------------------------
And my base table hbm.xml looks as follows (entity_one / entity_two)
<class name="com.pojos.EntityOne" table="entity_one">
<id name="oid" type="java.lang.String">
<column name="OID" scale="50" precision="0" not-null="true" unique="true" sql-type="VARCHAR2" />
<generator class="uuid.hex" />
</id>
...........
<set name="extnFields" lazy="true" cascade="all"> <key> <column name="ENTITY_OID" scale="50" precision="0" not-null="true" /> </key> <one-to-many class="com.pojos.EntityExtn" /> </set>
</class>
Q1. When I load EntityOne (or EntityTwo) it should return set of corresponding extn name-values (using outer join) - WORKING AS EXPECTED.
Q2. When I try to save EntityOne instance containing set of name-value instances, it cannot save the extn fields.
EntityOne entityOne = new EntityOne(); entityOne.setField1("Srikanth");
EntityExtn ee = new EntityExtn(); ee.setExtnName("car.type"); ee.setExtnValue("Mercedes"); Set s = new HashSet(); s.add(ee); entityOne.setExtnFields(s);
session.save(entityOne);
NOTE: I don't want to save entityOne before saving extn fields. Trying to achieve seemless insertion.
Anybody any idea?
Thank you
org.hibernate.PropertyValueException: not-null property references a null or transient value: com.artymedia.mdo.common.pojos.EntityExtn.entityOid
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:163)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:190)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:70)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:669)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:293)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:86)
at test.artymedia.mdo.pojo.insert._BaseTest.tearDown(_BaseTest.java:47)
at junit.framework.TestCase.runBare(TestCase.java:130)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:474)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:342)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:194)
|