-->
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.  [ 1 post ] 
Author Message
 Post subject: Hibernate Inheritance issues
PostPosted: Mon Sep 15, 2008 12:08 am 
Newbie

Joined: Sun Sep 14, 2008 4:00 pm
Posts: 1
Hibernate version:3.2.6

Code between sessionFactory.openSession() and session.close():I'm using Spring to do that

Name and version of the database you are using: MySQL, version: 5.0.51b-community-nt

Hi there,

I am having a problem with Hibernate inheritance. In the system that I plan to create, I have three types of objects; a location, and two types of coupons - active coupons and inactive coupons. Each location will have one active coupon associated with it, and one or many inactive coupons associated with it. Each time a new coupon is created for a location, if there is an existing coupon associated with it that is active, the old one becomes inactive and the new one automatically becomes the new one. I plan to have a class called 'Location', where it has a reference to a 'ActiveCoupon' object, and a collection of multiple 'PastCoupon' objects.

The ActiveCoupon and PostCoupon classes are subclasses from the Coupon class. Both of them have the exact same properties as the Coupon class. I intend to use inheritance in this system. What I wanted to do was to store the objects created from ActiveCoupon and PostCoupon in one table, which is why I used the table per class hierarchy strategy. Below is the hibernate mapping for my Location class mapping:

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="com.rfid.data.entity">
   <meta attribute="class-description">Represents a location</meta>
   <class name="Location" table="Location">
      <id name="id" type="long" column="locationID">
         <generator class="native" />
      </id>
      <property name="locationName" type="string" />
      <property name="distribution" type="boolean" />
      <property name="locationFor" type="long" />
      <one-to-one name="activeCoupon" class="ActiveCoupon" />
      <bag name="pastCoupons" lazy="false" where="isActive = 'Inactive'">
         <key column="locationID" />
         <one-to-many class="PastCoupon" />
      </bag>
   </class>
   <query name="fromLocation">
    <![CDATA[
from Location
      ]]>
   </query>
</hibernate-mapping>


My Coupon class mapping:
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="com.rfid.data.entity">
   <meta attribute="class-description">Represents a coupon</meta>
   <class name="Coupon" table="Coupon" lazy="false">
      <id name="id" type="long" column="couponID">
         <generator class="native" />
      </id>
      <discriminator type="string" column="isActive" />
      <property name="endDate" type="timestamp" />
      <property name="startDate" type="timestamp" />
      <property name="couponText" type="string" />
      <many-to-one name="location" class="Location" column="locationID"
          />
      <subclass name="ActiveCoupon" discriminator-value="Active">
      </subclass>
      <subclass name="PastCoupon" discriminator-value="Inactive">
         <property name="expiryDate" type="timestamp" />
      </subclass>
   </class>
   <query name="fromCoupon">
    <![CDATA[
from Coupon
      ]]>
   </query>
</hibernate-mapping>


And my Coupon code:
Code:
package com.rfid.data.entity;

import java.io.Serializable;
import java.util.Date;

@SuppressWarnings("serial")
public class Coupon implements Serializable
{
    private long id;
    private Date endDate;
    private Date startDate;
    private String couponText;
    private Location location;
    private String isActive;



    public String getIsActive()
    {
        return isActive;
    }



    public void setIsActive(String isActive)
    {
        this.isActive = isActive;
    }



    public String getCouponText()
    {
   return couponText;
    }



    public void setCouponText(String couponText)
    {
   this.couponText = couponText;
    }



    public Location getLocation()
    {
   return location;
    }



    public void setLocation(Location location)
    {
   this.location = location;
    }



    public long getId()
    {
   return id;
    }



    public void setId(long id)
    {
   this.id = id;
    }



    public Date getStartDate()
    {
   return startDate;
    }



    public void setStartDate(Date startDate)
    {
   this.startDate = startDate;
    }



    public Date getEndDate()
    {
   return endDate;
    }



    public void setEndDate(Date endDate)
    {
   this.endDate = endDate;
    }

}


And my location code:
Code:
package com.rfid.data.entity;

import java.util.Collection;

public class Location
{
    private long id;
    private String locationName;
    private boolean distribution;
    private long locationFor;
    private ActiveCoupon activeCoupon;
    private Collection<Coupon> pastCoupons;



    public boolean isDistribution()
    {
   return distribution;
    }



    public void setDistribution(boolean distribution)
    {
   this.distribution = distribution;
    }






    public ActiveCoupon getActiveCoupon()
    {
        return activeCoupon;
    }



    public void setActiveCoupon(ActiveCoupon activeCoupon)
    {
        this.activeCoupon = activeCoupon;
    }



    public Collection<Coupon> getPastCoupons()
    {
   return pastCoupons;
    }



    public void setPastCoupons(Collection<Coupon> pastCoupons)
    {
   this.pastCoupons = pastCoupons;
    }



    public long getId()
    {
   return id;
    }



    public void setId(long id)
    {
   this.id = id;
    }



    public String getLocationName()
    {
   return locationName;
    }



    public void setLocationName(String locationName)
    {
   this.locationName = locationName;
    }



    public long getLocationFor()
    {
   return locationFor;
    }



    public void setLocationFor(long locationFor)
    {
   this.locationFor = locationFor;
    }

}


One problem I initially encountered was changing the class type of the ActiveCoupon to a PostCoupon. I tried writing a property for the Coupon class named "isActive" (the same as the discriminator name) then changing it to "Inactive", but after persisting it the changes were not made to the DB. I then wrote a dirty way to change the type using a query:

Code:
    public void changeActiveCouponType(Coupon activeCoupon)
    {
   session = getSession ( );
   String hqlUpdate = "update Coupon set isActive = 'Inactive' where couponID = :id";
   Query query = session.createQuery ( hqlUpdate );
   query.setLong ( "id",activeCoupon.getId ( ) );
   query.executeUpdate ( );
   if ( session != null )
       session.close ( );
    }


It did make the changes, but unfortunately, after I inserted two coupons A and B (B should be active and A inactive) when I tried to get the location's Active Coupon after creating a new one it still retrieves A only. Meanwhile, the list of pastCoupons retrieves a list of ALL coupons, regardless of whether it is active or inactive. I inserted the where="isActive = 'Inactive'" property to it to trim down the results, but I expected Hibernate to do this for me. Can anyone tell me if there is a better way to change the subclass type and how to get Hibernate to correctly map the ActiveCoupon and PastCoupon properties correctly?

I would really appreciate it if someone could help me on this. Thanks in advance!


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

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.