| Hello I cannot figure this out.
 I have 2 base classes each with 2 subclasses like this
 
 Parent
 
 Parent1 extends Parent
 
 Parent2 extends Parent
 
 and
 
 Child
 
 Child1 extends Child
 
 Child2 extends Child
 
 Child1 has a many to one relationship with Parent1
 Child2 has a many to one relationship with Parent2
 
 Here is the code
 
 package org.marcus;
 
 import java.io.Serializable;
 import java.util.Date;
 import java.util.Set;
 import org.apache.commons.lang.builder.ToStringBuilder;
 /**
 * @author Marcus
 * @hibernate.class  table="child"
 *  discriminator-value="M"
 * @hibernate.discriminator column="type" type="character"
 * Represents a contact.
 */
 public class Child {
 long child_id = -1;
 
 /** Creates a new instance of Child */
 public Child() {
 }
 
 /**
 * @hibernate.id unsaved-value="-1"  generator-class="native"
 */
 public long getChild_id() {
 return child_id;
 }
 
 /**
 * Setter for property child_id.
 * @param child_id New value of property child_id.
 */
 public void setChild_id(long child_id) {
 this.child_id = child_id;
 }
 
 
 public String toString() {
 return new ToStringBuilder(this)
 .append("id", getChild_id())
 .toString();
 }
 
 public boolean equals(Object other) {
 if ( (this == other ) ) return true;
 if ( !(this.getClass().isInstance(other)))  return false;
 Child castOther = (Child) other;
 if(this.child_id == castOther.child_id)return true;
 return false;
 }
 
 public int hashCode() {
 return (int)child_id;
 }
 }
 
 package org.marcus;
 
 /**
 *
 * @author  marcus
 *@hibernate.subclass table="child" discriminator-value="P"
 */
 public class Child1 extends Child{
 Parent1 parent;
 /** Creates a new instance of Child1 */
 public Child1() {
 }
 
 /**
 * @hibernate.many-to-one name="parent" column="parent_id" class="org.marcus.Parent1" not-null="true"
 *
 */
 public Parent1 getParent() {
 return parent;
 }
 
 /**
 * Setter for property parent.
 * @param parent New value of property parent.
 */
 public void setParent(Parent1 parent) {
 this.parent = parent;
 }
 }
 
 package org.marcus;
 
 /**
 *
 * @author  marcus
 *@hibernate.subclass table="child" discriminator-value="Z"
 */
 public class Child2 extends Child{
 Parent2 parent;
 /** Creates a new instance of Child2 */
 public Child2() {
 }
 /**
 * @hibernate.many-to-one name="parent" column="parent_id" class="org.marcus.Parent2" not-null="true"
 *
 */
 public Parent2 getParent() {
 return parent;
 }
 
 /**
 * Setter for property parent.
 * @param parent New value of property parent.
 */
 public void setParent(Parent2 parent) {
 this.parent = parent;
 }
 }
 
 Here are the parents
 
 package org.marcus;
 import java.io.Serializable;
 import java.util.Date;
 import java.util.*;
 import org.apache.commons.lang.builder.ToStringBuilder;
 
 
 public class Parent {
 private long parent_id = -1;
 
 private String name;
 /** Creates a new instance of Parent */
 public Parent() {
 }
 
 /**
 * @hibernate.id unsaved-value="-1"  generator-class="native"
 */
 public long getParent_id() {
 return parent_id;
 }
 
 /**
 * Setter for property parent_id.
 * @param parent_id New value of property parent_id.
 */
 public void setParent_id(long parent_id) {
 this.parent_id = parent_id;
 }
 
 
 
 /**
 * @hibernate.property
 */
 public java.lang.String getName() {
 return name;
 }
 
 /**
 * Setter for property name.
 * @param name New value of property name.
 */
 public void setName(java.lang.String name) {
 this.name = name;
 }
 
 
 
 public String toString() {
 return new ToStringBuilder(this)
 .append("id", getParent_id())
 .toString();
 }
 
 public boolean equals(Object other) {
 if ( (this == other ) ) return true;
 if ( !(this.getClass().isInstance(other)))  return false;
 Parent castOther = (Parent) other;
 if(this.parent_id == castOther.parent_id)return true;
 return false;
 }
 
 public int hashCode() {
 return (int)parent_id;
 }
 
 }
 package org.marcus;
 import java.io.Serializable;
 import java.util.Date;
 import java.util.*;
 import org.apache.commons.lang.builder.ToStringBuilder;
 /**
 * @author Marcus
 * @hibernate.class  table="parent1"
 * Represents a contact.
 */
 public class Parent1 extends Parent{
 private Set children = new HashSet();
 /** Creates a new instance of Parent1 */
 public Parent1() {
 }
 
 public void addChild(Child1 c) {
 c.setParent(this);
 getChildren().add(c);
 }
 
 /**
 * @hibernate.set name="children" inverse="true" cascade="all-delete-orphan"
 *
 * @hibernate.collection-key column="parent_id"
 * @hibernate.collection-one-to-many class="org.marcus.Child1"
 * @return
 */
 public java.util.Set getChildren() {
 return children;
 }
 
 /**
 * Setter for property children.
 * @param children New value of property children.
 */
 public void setChildren(java.util.Set children) {
 this.children = children;
 }
 }
 
 package org.marcus;
 import java.io.Serializable;
 import java.util.Date;
 import java.util.*;
 import org.apache.commons.lang.builder.ToStringBuilder;
 /**
 * @author Marcus
 * @hibernate.class  table="parent2"
 * Represents a contact.
 */
 public class Parent2 extends Parent{
 private Set children = new HashSet();
 /** Creates a new instance of Parent2 */
 public Parent2() {
 }
 
 public void addChild(Child2 c) {
 c.setParent(this);
 getChildren().add(c);
 }
 
 /**
 * @hibernate.set name="children" inverse="true" cascade="all-delete-orphan"
 *
 * @hibernate.collection-key column="parent_id"
 * @hibernate.collection-one-to-many class="org.marcus.Child2"
 * @return
 */
 public java.util.Set getChildren() {
 return children;
 }
 
 /**
 * Setter for property children.
 * @param children New value of property children.
 */
 public void setChildren(java.util.Set children) {
 this.children = children;
 }
 }
 
 Here are the generated mappings from XDoclet
 
 <?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="org.marcus.Child"
 table="child"
 dynamic-update="false"
 dynamic-insert="false"
 discriminator-value="M"
 >
 
 <id
 name="child_id"
 column="child_id"
 type="long"
 unsaved-value="-1"
 >
 <generator class="native">
 </generator>
 </id>
 
 <discriminator
 column="type"
 type="character"
 />
 
 <!--
 To add non XDoclet property mappings, create a file named
 hibernate-properties-Child.xml
 containing the additional properties and place it in your merge dir.
 -->
 <subclass
 name="org.marcus.Child1"
 dynamic-update="false"
 dynamic-insert="false"
 discriminator-value="P"
 >
 
 <many-to-one
 name="parent"
 class="org.marcus.Parent1"
 cascade="none"
 outer-join="auto"
 update="true"
 insert="true"
 access="property"
 column="parent_id"
 not-null="true"
 />
 
 <!--
 To add non XDoclet property mappings, create a file named
 hibernate-properties-Child1.xml
 containing the additional properties and place it in your merge dir.
 -->
 
 </subclass>
 <subclass
 name="org.marcus.Child2"
 dynamic-update="false"
 dynamic-insert="false"
 discriminator-value="Z"
 >
 
 <many-to-one
 name="parent"
 class="org.marcus.Parent2"
 cascade="none"
 outer-join="auto"
 update="true"
 insert="true"
 access="property"
 column="parent_id"
 not-null="true"
 />
 
 <!--
 To add non XDoclet property mappings, create a file named
 hibernate-properties-Child2.xml
 containing the additional properties and place it in your merge dir.
 -->
 
 </subclass>
 
 </class>
 
 </hibernate-mapping>
 
 <?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="org.marcus.Parent1"
 table="parent1"
 dynamic-update="false"
 dynamic-insert="false"
 >
 
 <id
 name="parent_id"
 column="parent_id"
 type="long"
 unsaved-value="-1"
 >
 <generator class="native">
 </generator>
 </id>
 
 <set
 name="children"
 lazy="false"
 inverse="true"
 cascade="all-delete-orphan"
 sort="unsorted"
 >
 
 <key
 column="parent_id"
 >
 </key>
 
 <one-to-many
 class="org.marcus.Child1"
 />
 </set>
 
 <property
 name="name"
 type="java.lang.String"
 update="true"
 insert="true"
 access="property"
 column="name"
 />
 
 <!--
 To add non XDoclet property mappings, create a file named
 hibernate-properties-Parent1.xml
 containing the additional properties and place it in your merge dir.
 -->
 
 </class>
 
 </hibernate-mapping>
 <?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="org.marcus.Parent2"
 table="parent2"
 dynamic-update="false"
 dynamic-insert="false"
 >
 
 <id
 name="parent_id"
 column="parent_id"
 type="long"
 unsaved-value="-1"
 >
 <generator class="native">
 </generator>
 </id>
 
 <set
 name="children"
 lazy="false"
 inverse="true"
 cascade="all-delete-orphan"
 sort="unsorted"
 >
 
 <key
 column="parent_id"
 >
 </key>
 
 <one-to-many
 class="org.marcus.Child2"
 />
 </set>
 
 <property
 name="name"
 type="java.lang.String"
 update="true"
 insert="true"
 access="property"
 column="name"
 />
 
 <!--
 To add non XDoclet property mappings, create a file named
 hibernate-properties-Parent2.xml
 containing the additional properties and place it in your merge dir.
 -->
 
 </class>
 
 </hibernate-mapping>
 
 
 If I run this snippet of code
 
 Parent1 p = new Parent1();
 Child1 c = new Child1();
 p.addChild(c);
 session.save(p);
 session.flush();
 
 I get this error
 19:29:16,305  WARN JDBCExceptionReporter:38 - SQL Error: 0, SQLState: null
 19:29:16,306 ERROR JDBCExceptionReporter:46 - Batch entry 0 insert into child (parent_id, type, child_id) values ( was aborted. Call getNextException() to see the cause.
 19:29:16,309  WARN JDBCExceptionReporter:38 - SQL Error: 0, SQLState: 23503
 19:29:16,309 ERROR JDBCExceptionReporter:46 - ERROR: insert or update on table "child" violates foreign key constraint "fk5a3f51c7b66b0d0b9579e27"
 
 19:29:16,313  WARN JDBCExceptionReporter:38 - SQL Error: 0, SQLState: null
 19:29:16,314 ERROR JDBCExceptionReporter:46 - Batch entry 0 insert into child (parent_id, type, child_id) values ( was aborted. Call getNextException() to see the cause.
 19:29:16,314  WARN JDBCExceptionReporter:38 - SQL Error: 0, SQLState: 23503
 19:29:16,315 ERROR JDBCExceptionReporter:46 - ERROR: insert or update on table "child" violates foreign key constraint "fk5a3f51c7b66b0d0b9579e27"
 
 19:29:16,317 ERROR JDBCExceptionReporter:38 - Could not execute JDBC batch update
 Batch entry 0 insert into child (parent_id, type, child_id) values ( was aborted. Call getNextException() to see the cause.
 at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:107)
 at com.mchange.v2.sql.filter.FilterPreparedStatement.executeBatch(FilterPreparedStatement.java:260)
 at net.sf.hibernate.impl.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:54)
 at net.sf.hibernate.impl.BatcherImpl.executeBatch(BatcherImpl.java:122)
 at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2410)
 at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2360)
 at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2229)
 at Jubilee.Jubilee.main(Jubilee.java:76)
 19:29:16,319 ERROR SessionImpl:2368 - Could not synchronize database state with session
 net.sf.hibernate.JDBCException: Could not execute JDBC batch update
 at net.sf.hibernate.impl.BatcherImpl.executeBatch(BatcherImpl.java:129)
 at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2410)
 at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2360)
 at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2229)
 at Jubilee.Jubilee.main(Jubilee.java:76)
 
 ad infinitum.
 Obviously hibernate is not providing a value to link the child1 object with its parent1 object
 
 If I remove the Child2 Parent2 references completely it works fine.
 
 If I run this snippet with Parent1 Child1 out of the picture
 Parent2 p = new Parent2();
 Child2 c = new Child2();
 p.addChild(c);
 session.save(p);
 session.flush();
 
 It also runs fine
 Perhaps my concept of discriminator is wrong. What I really want to achieve is the following
 Child Object can have a many to one relationship with either an instance of Parent 1 or Parent2 or ParentX but cant exist without either a Parent1 or a Parent2 or ParentX
 
 Looking at the generated sql. I can see the reason its failing. For some reason its using foreign keys which can never be satisfied. What is the point of having a discriminator value if its also going to use foreign keys
 
 alter table child drop constraint FK5A3F51C7B66B0D0;
 alter table child drop constraint FK5A3F51C7B66B0D0B9579E27;
 drop table child;
 drop table parent1;
 drop table parent2;
 drop sequence hibernate_sequence;
 create table child (
 child_id INT8 not null,
 type CHAR(1) not null,
 parent_id INT8 not null,
 primary key (child_id)
 );
 create table parent1 (
 parent_id INT8 not null,
 name VARCHAR(255),
 primary key (parent_id)
 );
 create table parent2 (
 parent_id INT8 not null,
 name VARCHAR(255),
 primary key (parent_id)
 );
 alter table child add constraint FK5A3F51C7B66B0D0 foreign key (parent_id) references parent1;
 alter table child add constraint FK5A3F51C7B66B0D0B9579E27 foreign key (parent_id) references parent2;
 create sequence hibernate_sequence;
 
 
 Any help would be appreciated
 
 Marcus
 
 
 |