-->
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.  [ 4 posts ] 
Author Message
 Post subject: Discriminator type with annotations
PostPosted: Sun Mar 02, 2008 4:01 pm 
Newbie

Joined: Sun Mar 02, 2008 3:43 pm
Posts: 9
Hello,

I'm new to hibernate, and trying to port my home-made application to hibernate.

I'm a willing to use an userType as a discriminator.

I have written an EnhancedUserType for this and succeed to use it with hibernate xml.

My problem is that I wanted to use annotations and I can't figure out how to specify the discriminator type.

discriminationType in @DiscriminationColumn seem to take only a enum value and not a type name.

Is there an annotation I'm missing ?
am I forced to use xml notation ?
is there a way to add my own annotations?
Is there a way to mix xml notations with annotations? Apparently I can't figure out this configuration un JPA xml either.


See below for working xml config file. The discriminator returns a string with fully qualified classpath.

Any help welcome :)


Code:
<hibernate-mapping package="com.dg.sim.backend.operationlog" default-access="field">
   <typedef name="com.dg.sim.backend.operations.Operation.Discriminator"
      class="com.dg.persistence.hibernate.userType.ObjectDiscriminatorUserType">
      <param name="class">com.dg.sim.backend.operations.Operation</param>
   </typedef>
  <class name="OperationLog" table="operation_log" discriminator-value="PERSO">
        
        <id name="id" type="com.dg.persistence.hibernate.userType.BasicIndexUserType"/>
        <discriminator formula="Op_Id" type="com.dg.sim.backend.operations.Operation.Discriminator"/>
        <!--  <discriminator column="DTYPE" type="string"/>-->
        <property name="jId" column="J_id" type="com.dg.persistence.hibernate.userType.BasicIndexUserType"/>
        <property name="operation" column="Op_Id">
           <type name="com.dg.persistence.hibernate.userType.ObjectUserType">
              <param name="class">com.dg.sim.backend.operations.Operation</param>
           </type>
        </property>
        <many-to-one name="joueur" column="J_id" not-null="true" class="com.dg.sim.backend.Joueur" insert="false"
        update="false"/>
        <property name="date"/>
        <property name="realdate"/>
        <property name="oldKarma" column="oldkarma"/>
        <property name="karma"/>
        <property name="newKarma" column="newkarma"/>
        <property name="status"/>
        <property name="log"/>
        <property name="freeString"/>
        <subclass name="OperationTest">
              <property name="karm" column="val1"/>
        </subclass>
        <subclass name="OperationPersoLog">
              <property name="persoId" column="idx1" type="com.dg.persistence.hibernate.userType.BasicIndexUserType"/>
              <property name="argent" column="money1" type="com.dg.persistence.hibernate.userType.MoneyUserType"/>
              <property name="moral" column="val1" />
              <property name="stress" column="val2"/>
              <property name="social" column="val3"/>
              <property name="argentN" column="n_money1" type="com.dg.persistence.hibernate.userType.MoneyUserType"/>
              <property name="moralN" column="n_val1"/>
              <property name="stressN" column="n_val2"/>
              <property name="socialN" column="n_val3"/>            
        </subclass>
  </class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 03, 2008 4:09 pm 
Newbie

Joined: Sun Mar 02, 2008 3:43 pm
Posts: 9
Nobody knows?

I've gone through hibernate source as far as I can understand it, it can't be done with annotations.
I still have to look for JPA xml files.

I'm stuck with 3 options:
1)use hibernate xml format.
2)don't use usertype discriminator
3)add a personal annotation.

for 3) I imagine something like this:

get all persistent classes from configuration and iterate them. If they have a discriminator, look for my own annotation and add it to the discriminator.
Seems feasible to me.

am I missing something obvious ?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 03, 2008 10:45 pm 
Newbie

Joined: Sun Mar 02, 2008 3:43 pm
Posts: 9
I worked on 3) and I got to something apparently working.

I'm still a little bit worried, I worked my way by reading more code than documentation, So I'm not quite sure it is a nice way to do it or a bad hack
that would break with next version.

I am also still wondering if there isn't any other way to implement discriminatorType with annotations.



I past the code there in case it is any use to someone. (although I mean to be speaking to myself here)




Attention: you need to use cfg.buildEntityManagerFactory() after that
and nor Persistence.createEntityManagerFactory() otherwise you'll work with another Factory.


Code:
      org.hibernate.ejb.Ejb3Configuration cfg=new org.hibernate.ejb.Ejb3Configuration();
      cfg.configure("myconf",null);
      debug(ConfigurationEnhancer.class," configure done ");
      Mappings mappings=cfg.getHibernateConfiguration().createMappings();
      for(Iterator it=cfg.getClassMappings();it.hasNext();){         
         PersistentClass classe=(PersistentClass) it.next();
         debug(ConfigurationEnhancer.class,"checking ",classe," for Discrimator");
         SimpleValue value=(SimpleValue)classe.getDiscriminator();
         if(value!=null){
            String name=classe.getClassName();
            try{
               debug(ConfigurationEnhancer.class,"checking ",name," for user DiscrimatorType");
               Class maClasse=Class.forName(name);
               if(maClasse.isAnnotationPresent(DiscriminatorType.class)){
                  DiscriminatorType type=(DiscriminatorType) maClasse.getAnnotation(DiscriminatorType.class);
                  String typeName=type.type();
                  debug(ConfigurationEnhancer.class,"annotation present in",name,"type",typeName);
                  TypeDef typeDef=mappings.getTypeDef(typeName);
                  if(typeDef!=null){
                     debug(ConfigurationEnhancer.class,"typedef found for",typeName);
                     typeName=typeDef.getTypeClass();
                     // parameters on the property mapping should
                     // override parameters in the typedef
                     Properties parameters = new Properties();
                     parameters.putAll( typeDef.getParameters() );
                     if ( !parameters.isEmpty() ) value.setTypeParameters( parameters );      
                  }
                  debug(ConfigurationEnhancer.class,"set type",typeName);
                  if ( typeName != null ) value.setTypeName( typeName );
               }
            }
            catch(ClassNotFoundException e){
               staticError(ConfigurationEnhancer.class,e);
            }
         }
      }


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 04, 2008 4:53 pm 
Newbie

Joined: Sun Mar 02, 2008 3:43 pm
Posts: 9
Apparently my patch works but bug if Tomcat have a Session.ser on but.
It must do some kind of deserialization that would block my hack in some way.

I'd really like some help for some right way to do that.


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