-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: How to persist a class that has subclasses?
PostPosted: Mon Feb 02, 2004 10:44 am 
Pro
Pro

Joined: Wed Oct 08, 2003 10:31 am
Posts: 247
I'm trying to use a framework that I found recently. In the DB I have the ACTOR table. My problem is how do I associate the two subclasses (GroupImpl and UserImpl) to a ActorImpl so I can save it!?

I have the following files:

-----------------
Mapping file
-----------------
ActorImpl
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="org.ActorImpl"
        table="ACTOR"
        dynamic-update="false"
        dynamic-insert="false"
        discriminator-value="Actor"
    >

        <id
            name="id"
            column="id"
            type="string"
            unsaved-value="null"
        >
            <generator class="assigned">
            </generator>
        </id>

        <discriminator
            column="subclass"
            type="string"
        />

        <subclass
            name="org.GroupImpl"
            dynamic-update="false"
            dynamic-insert="false"
            discriminator-value="Group"
        >
        <property
            name="name"
            type="string"
            update="true"
            insert="true"
            column="name"
        />

        <property
            name="type"
            type="string"
            update="true"
            insert="true"
            column="type_"
        />

        <set
            name="memberships"
            lazy="true"
            inverse="false"
            cascade="all"
            sort="unsorted"
        >

              <key
                  column="group_"
              />

              <one-to-many
                  class="org.MembershipImpl"
              />
        </set>

        <many-to-one
            name="parent"
            class="org.GroupImpl"
            cascade="all"
            outer-join="auto"
            update="true"
            insert="true"
            column="parent"
        />

        <set
            name="children"
            lazy="true"
            inverse="false"
            cascade="all"
            sort="unsorted"
        >

              <key
                  column="parent"
              />

              <one-to-many
                  class="org.GroupImpl"
              />
        </set>

        </subclass>
        <subclass
            name="org.UserImpl"
            dynamic-update="false"
            dynamic-insert="false"
            discriminator-value="User"
        >
        <property
            name="firstName"
            type="string"
            update="true"
            insert="true"
            column="firstName"
        />

        <property
            name="lastName"
            type="string"
            update="true"
            insert="true"
            column="lastName"
        />

        <property
            name="email"
            type="string"
            update="true"
            insert="true"
            column="email"
        />

        <set
            name="memberships"
            lazy="true"
            inverse="false"
            cascade="all"
            sort="unsorted"
        >

              <key
                  column="user_"
              />

              <one-to-many
                  class="org..MembershipImpl"
              />
        </set>
        </subclass>
    </class>
</hibernate-mapping>


---------
POJO
---------
ActorImpl
Code:
package org;

/**
* @hibernate.class table="ACTOR" discriminator-value="Actor"
* @hibernate.discriminator column="subclass" type="string"
*/
public abstract class ActorImpl implements Actor, Comparable {

  /**
   * @hibernate.id column="id" type="string" unsaved-value="null" generator-class="assigned"
   */   
  public String getId() { return this.id; }
  public void setId(String id) { this.id = id; }

  // toString
  public String toString() {
    String className = this.getClass().getName();
    int to = className.length();
    if ( className.endsWith( "Impl" ) ) {
      to = to - 4;
    }
    int from = className.lastIndexOf( '.' ) + 1;
    className = className.substring( from, to );
    return className + "[" + id + "]"; 
  }
 
  // equals
  public boolean equals( Object object ) {
    boolean isEqual = false;
    if ( ( object != null )
         && ( object instanceof ActorImpl ) ) {
           ActorImpl actor = (ActorImpl) object;
      if ( ( this.id == null )
           && ( actor.id == null ) ) {
        isEqual = ( this == actor );
      } else if ( ( this.id != null )
                  && ( actor.id != null ) ) {
        isEqual = this.id.equals( actor.id );
      }
    }
    return isEqual;
  }
 
  // hashCode
  public int hashCode() {
    int hashCode = 0;
    if ( id != null ) {
      hashCode = id.hashCode();
    } else {
      super.hashCode();
    }
    return hashCode;
  }

  // compareTo 
  public int compareTo(Object object) {
    int difference = -1;
   
    ActorImpl actor = (ActorImpl) object;
    if ( ( actor != null )
         && ( this.id != null )
         && ( actor.id != null ) ) {
      difference = this.id.compareTo( actor.id );
    } else {
      throw new RuntimeException( "can't compare two actors this(" + this + ") and object(" + object + ")" );
    }

    return difference;
  }

  protected String id = null;
}


UserImpl
Code:
package org;

import java.util.*;

/**
* @hibernate.subclass discriminator-value="User"
*/
public class UserImpl extends ActorImpl implements User {
 
  /**
   * @hibernate.property type="string" column="firstName"
   */
  public String getFirstName() { return firstName; }
  public void setFirstName(String firstName) { this.firstName = firstName; }
 
  /**
   * @hibernate.property type="string" column="lastName"
   */
  public String getLastName() { return lastName; }
  public void setLastName(String lastName) { this.lastName = lastName; }
 
  /**
   * @hibernate.property type="string" column="email"
   */
  public String getEmail() { return email; }
  public void setEmail(String email) { this.email = email; }
 
  /**
   * @hibernate.set lazy="true" cascade="all"
   * @hibernate.collection-key column="user_"
   * @hibernate.collection-one-to-many class="org.MembershipImpl"
   */
  public Collection getMemberships() { return memberships; }
  public void setMemberships(Collection memberships) { this.memberships = memberships; }

  // wrapper method
  public String getName() {
    return getFirstName() + " " + getLastName();
  }
 
  // private members
  private String firstName = null;
  private String lastName = null;
  private String email = null;
  private Collection memberships = null;
}


GroupImpl
Code:
package org;

import java.util.*;

/**
* @hibernate.subclass discriminator-value="Group"
*/
public class GroupImpl extends ActorImpl implements Group {
 
  /**
   * @hibernate.property type="string" column="name"
   */
  public String getName() { return this.name; }
  public void setName(String name) { this.name = name; }
 
  /**
   * @hibernate.property type="string" column="type_"
   */
  public String getType() { return type; }
  public void setType(String type) { this.type = type; }
 
  /**
   * @hibernate.set lazy="true" cascade="all"
   * @hibernate.collection-key column="group_"
   * @hibernate.collection-one-to-many class="org.MembershipImpl"
   */
  public Collection getMemberships() { return memberships; }
  public void setMemberships(Collection memberships) { this.memberships = memberships; }
 
  /**
   * @hibernate.many-to-one class="org.GroupImpl"
   *  cascade="all"
   */
  public Group getParent() { return parent; }
  public void setParent(Group parent) { this.parent = parent; }
 
  /**
   * @hibernate.set lazy="true" cascade="all"
   * @hibernate.collection-key column="parent"
   * @hibernate.collection-one-to-many class="org.GroupImpl"
   */
  public Collection getChildren() { return children; }
  public void setChildren(Collection children) { this.children = children; }
 
  // private members
  private String name = null;
  private String type = null;
  private Collection memberships = null;
  private Group parent = null;
  private Collection children = null;
}


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 02, 2004 10:46 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Well, it is a Subclass... just create an instance and save it.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 02, 2004 10:51 am 
Pro
Pro

Joined: Wed Oct 08, 2003 10:31 am
Posts: 247
gloeglm wrote:
Well, it is a Subclass... just create an instance and save it.


Thanks for the quick reply.
Hmm... then if I save an instance of UserImpl and GroupImpl subclasses and then save a ActorImpl isntance, I will have the subclass instances associated with the class in one DB register in ACTOR table?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 02, 2004 10:59 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Well no, they are seperate instances, so seperate database rows. But your mapping is strange anyways, Group and User being Subclasses of Actor is very strange, there is no is-a relationship here as far as I understand. You should rather use associations imho.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 02, 2004 11:03 am 
Pro
Pro

Joined: Wed Oct 08, 2003 10:31 am
Posts: 247
gloeglm wrote:
Well no, they are seperate instances, so seperate database rows. But your mapping is strange anyways, Group and User being Subclasses of Actor is very strange, there is no is-a relationship here as far as I understand. You should rather use associations imho.


Your right.
I have the same opinion. The mapping is in fact strange.
But my problem is that it has only the ACTOR table. And a register in this table represents the information of the class and it's 2 subclasses. It represents a single row. :-(


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 02, 2004 11:06 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
If you implement this using Inheritance one object can only be either a Group or a User. So if you store two different objects, Hibernate will keep two rows in the Database. This was allready discussed in excess here some time ago.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 02, 2004 11:08 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
http://forum.hibernate.org/viewtopic.php?t=927294&highlight=inheritance


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.