-->
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.  [ 2 posts ] 
Author Message
 Post subject: Discriminator: access to subclass
PostPosted: Fri Mar 14, 2008 8:06 am 
Newbie

Joined: Fri Mar 14, 2008 6:59 am
Posts: 6
Hi
I'm using Hibernate version:3.2.5 and I'm using the discriminator tag in hbm.xml file to specify some object's properties. This is my hbm:
Code:
<hibernate-mapping>
   <class name="it.aams.contenzioso.persistentObjects.CAnaRicorrenti" table="C_ANA_RICORRENTI">
      <cache usage="read-only" />
      <id name="idk" type="long">
         <column name="IDK" precision="22" scale="0" />
         <generator class="sequence">
            <param name="sequence">SEQ_ANA_RICORRENTI</param>
         </generator>
      </id>
      
      <discriminator column="TIPO_PERSONA" type="string" insert="false" />
      
      <many-to-one name="CSTipoPersona" class="it.aams.contenzioso.persistentObjects.CSTipoPersona" fetch="select" lazy="false">
         <column name="TIPO_PERSONA" precision="22" scale="0" />
      </many-to-one>
      
      <property name="comune" type="string">
         <column name="COMUNE" length="50" />
      </property>
      <property name="provincia" type="string">
         <column name="PROVINCIA" length="2" />
      </property>
      <property name="isRicorrenteProvvCU" type="integer">
         <column name="IS_RICORRENTE_PROVV_CU" precision="22" scale="0" length="1" />
      </property>
      
      <subclass name="it.aams.contenzioso.persistentObjects.CAnaRicorrentiFisica" discriminator-value="1">
         <property name="nome" type="string">
            <column name="NOME" length="50" />
         </property>
         <property name="cognome" type="string">
            <column name="COGNOME_DENOMINAZIONE" length="50" />
         </property>
         <property name="codiceFiscale" type="string">
            <column name="CF_IVA" length="16" />
         </property>
         <property name="dtNascita" type="timestamp">
            <column name="DT_NASCITA" length="7" />
         </property>
         <property name="domComune" type="string">
            <column name="DOM_COMUNE" length="60" />
         </property>
         <property name="domProvincia" type="string">
            <column name="DOM_PROVINCIA" length="2" />
         </property>
         <property name="domIndirizzo" type="string">
            <column name="DOM_INDIRIZZO" length="100" />
         </property>
      </subclass>
      
      <subclass name="it.aams.contenzioso.persistentObjects.CAnaRicorrentiGiuridica" discriminator-value="2">
         <property name="denominazione" type="string">
            <column name="COGNOME_DENOMINAZIONE" length="50" />
         </property>
         <property name="partitaIva" type="string">
            <column name="CF_IVA" length="16" />
         </property>
      </subclass>
      
   </class>
</hibernate-mapping>


As you can see I need a general Object containing the main property and 2 subclass extending the main object and having more specific features (properties) basing on the dicriminator column.

These are the persisting objects involved in the mapping:
This is the general object
Code:
public class CAnaRicorrenti implements Serializable
{
   public CAnaRicorrenti(){}

   public CAnaRicorrenti(long idk){
      this.setIdk(idk);
   }

   // primary key
   private long idk;

   // fields
   private java.lang.String nome;
   private java.lang.String cognomeDenominazione;
   private java.lang.String cfIva;
   private java.lang.String comune;
   private java.lang.String provincia;
   private java.util.Date dtNascita;
   private java.lang.String domComune;
   private java.lang.String domProvincia;
   private java.lang.String domIndirizzo;
   private java.lang.Integer isRicorrenteProvvCU;

   // many to one
   private it.aams.contenzioso.persistentObjects.CSTipoPersona cSTipoPersona;

   public long getIdk(){
      return idk;
   }

   public void setIdk(long idk){
      this.idk = idk;
   }

   protected java.lang.String getNome(){
      return nome;
   }

   protected void setNome(java.lang.String nome){
      this.nome = nome;
   }

   protected java.lang.String getCognomeDenominazione(){
      return cognomeDenominazione;
   }

   protected void setCognomeDenominazione(java.lang.String cognomeDenominazione){
      this.cognomeDenominazione = cognomeDenominazione;
   }

   protected java.lang.String getCfIva(){
      return cfIva;
   }

   protected void setCfIva(java.lang.String cfIva){
      this.cfIva = cfIva;
   }

   public java.lang.String getComune(){
      return comune;
   }

   public void setComune(java.lang.String comune){
      this.comune = comune;
   }

   public java.lang.String getProvincia(){
      return provincia;
   }

   public void setProvincia(java.lang.String provincia){
      this.provincia = provincia;
   }

   protected java.util.Date getDtNascita(){
      return dtNascita;
   }

   protected void setDtNascita(java.util.Date dtNascita){
      this.dtNascita = dtNascita;
   }

   protected java.lang.String getDomComune(){
      return domComune;
   }

   protected void setDomComune(java.lang.String domComune){
      this.domComune = domComune;
   }

   protected java.lang.String getDomProvincia(){
      return domProvincia;
   }

   protected void setDomProvincia(java.lang.String domProvincia){
      this.domProvincia = domProvincia;
   }

   protected java.lang.String getDomIndirizzo(){
      return domIndirizzo;
   }

   protected void setDomIndirizzo(java.lang.String domIndirizzo){
      this.domIndirizzo = domIndirizzo;
   }

   public it.aams.contenzioso.persistentObjects.CSTipoPersona getCSTipoPersona(){
      return cSTipoPersona;
   }

   public void setCSTipoPersona(it.aams.contenzioso.persistentObjects.CSTipoPersona cSTipoPersona){
      this.cSTipoPersona = cSTipoPersona;
   }
}


These are the subclasses:

Code:
public class CAnaRicorrentiFisica extends CAnaRicorrenti{
   public CAnaRicorrentiFisica(){
      super();
   }

   public CAnaRicorrentiFisica(long idk)
   {
      super(idk);
   }

   public java.lang.String getCodiceFiscale()
   {
      return super.getCfIva();
   }
   
   public void setCodiceFiscale(java.lang.String codiceFiscale)
   {
      super.setCfIva(codiceFiscale);
   }
   
   public java.lang.String getCognome(){
      return super.getCognomeDenominazione();
   }
   
   public void setCognome(java.lang.String cognome){
      super.setCognomeDenominazione(cognome);
   }
   
   public java.lang.String getDomComune(){
      return super.getDomComune();
   }
   
   public void setDomComune(java.lang.String domComune){
      super.setDomComune(domComune);
   }
   
   public java.lang.String getDomIndirizzo(){
      return super.getDomIndirizzo();
   }
   
   public void setDomIndirizzo(java.lang.String domIndirizzo){
      super.setDomIndirizzo(domIndirizzo);
   }
   
   public java.lang.String getDomProvincia(){
      return super.getDomProvincia();
   }
   
   public void setDomProvincia(java.lang.String domProvincia){
      super.setDomProvincia(domProvincia);
   }
   
   public java.util.Date getDtNascita(){
      return super.getDtNascita();
   }
   
   public void setDtNascita(java.util.Date dtNascita){
      super.setDtNascita(dtNascita);
   }
   
   public java.lang.String getNome(){
      return super.getNome();
   }
   
   public void setNome(java.lang.String nome){
      super.setNome(nome);
   }
}


Code:
public class CAnaRicorrentiGiuridica extends CAnaRicorrenti{
   public CAnaRicorrentiGiuridica(){
      super();
   }

   public CAnaRicorrentiGiuridica(long idk){
      super(idk);
   }

   public java.lang.String getDenominazione(){
      return super.getCognomeDenominazione();
   }
   
   public void setDenominazione(java.lang.String denominazione){
      super.setCognomeDenominazione(denominazione);
   }
   
   public java.lang.String getPartitaIva(){
      return super.getCfIva();
   }
   
   public void setPartitaIva(java.lang.String partitaIva){
      super.setCfIva(partitaIva);
   }
}


This is the junit code where I use this mapping:
Code:
      CAnaRicorrenti cAnaRicorrentiResult = cAnaRicorrentiDAO.getCAnaRicorrenti(new Long("644"));
      System.out.println("Idk: "+cAnaRicorrentiResult.getIdk());
      System.out.println("CSTipoPersona: "+cAnaRicorrentiResult.getCSTipoPersona().getIdk());
      System.out.println("Comune: "+cAnaRicorrentiResult.getComune());
      System.out.println("Provincia: "+cAnaRicorrentiResult.getProvincia());
      System.out.println("IsRicorrenteProvvCU: "+cAnaRicorrentiResult.getIsRicorrenteProvvCU());
      System.out.println("CSTipoRicorrenti: "+cAnaRicorrentiResult.getCSTipoRicorrenti().getIdk());
      System.out.println("CRicorsi: "+cAnaRicorrentiResult.getCRicorsi().getIdk());


As you can see I'm getting the properties of the general object, no problem until here.
But now I want to access the specific properties of the subclasses basing on the discriminator and here comes the problem.
Basing on the hbm.xml above, when calling a findbyPrimaryKey method, I supposed Hibernate would return a specific object (i.e. CAnaRicorrentiFisica) basing on TIPO_PERSONA value, so I could cast from the abstract supertype to the concrete child and easily access the specific properties, but when I execute the following code I get a ClassCastException:
Code:
if (cAnaRicorrentiResult.getCSTipoPersona().getIdk() == 2)
   {
      cAnaRicorrentiGiuridicaResult = (CAnaRicorrentiGiuridica)cAnaRicorrentiResult;
   }


I run the junit in debug mode and this is the detail of what Hibernate returned:
Image

As you can see, the returned object belongs to the supertype CAnaRicorrenti while CAnaRicorrentiGiuridica with its properties is included deep inside.

So here comes the question:
How can I access the specific properties of the specific objects?

Thanks in advance.
Feel free to ask more details if you need.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 19, 2008 6:58 am 
Newbie

Joined: Fri Mar 14, 2008 6:59 am
Posts: 6
I found the reason!

The superclass should have been defined with lazy="false":
Code:
<hibernate-mapping>
   <class name="it.aams.contenzioso.persistentObjects.CAnaRicorrenti" table="C_ANA_RICORRENTI" lazy="false">
      <id name="idk" type="long">
         <column name="IDK" precision="22" scale="0" />
         <generator class="sequence">
            <param name="sequence">SEQ_ANA_RICORRENTI</param>
         </generator>
      </id>
      
      <discriminator column="TIPO_PERSONA" type="string" insert="false" />

      ...

      <subclass name="it.aams.contenzioso.persistentObjects.CAnaRicorrentiFisica" discriminator-value="1">
         ...
      </subclass>
      
      <subclass name="it.aams.contenzioso.persistentObjects.CAnaRicorrentiGiuridica" discriminator-value="2">
         ...
      </subclass>

   </class>
</hibernate-mapping>


Now the object returned by Hibernate belongs to the subclasses (CAnaRicorrentiFisica or CAnaRicorrentiGiuridica) depending on discriminator and doesn't belong anymore to CAnaRicorrenti$$EnhancerByCGLIB5cabdf35


Hope this help to the next one facing my same problem.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 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.