-->
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.  [ 9 posts ] 
Author Message
 Post subject: NULL is 0 or 1 or 2 or 3
PostPosted: Mon Nov 15, 2004 6:01 am 
Expert
Expert

Joined: Thu Jan 29, 2004 2:31 am
Posts: 362
Location: Switzerland, Bern
Hibernate version:
2.1.6

Name and version of the database you are using:
Oracle 9i
Sybase 12

In our legacy DB some FKs are not just NULL if there's no PK in the corresponding table. Sometimes they get pseudo values which do have a special business meaning. So instead of NULL I've one of (0,1,2,3).

Based on the solutin discussed in
Code:
http://forum.hibernate.org/viewtopic.php?t=935678&highlight=


I'm able to do the following:
  1. Write a UserType to treat 0,1,2 and 3 as NULL for reading.
  2. In parallel to the <many-to-one> property I've an ordinary <property> mapping to the same column. The <many-to-one> is marked as insert=false and update=false.
  3. With an Interceptor.onLoad I set the <many-to-one> property to a DummyObject1, DummyObject2, ... depending on the value of the additional property.
  4. With an Interceptor.onFlushDirty/onSave I set the additinal property to 0,1,2, 3 or the real foreign key if the <many-to-one> is not a DummyObjectx.


My question is if there's an easyer way of solving this problem? Unfortunately changing the DB would involve killing some customers and DBAs ...

TIA
Ernst


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 15, 2004 7:08 am 
Expert
Expert

Joined: Tue Oct 05, 2004 9:45 am
Posts: 263
@ernst
and i thought my database-model is a tricky one ;)

Is it possible to determine in a generic way which value (0,1,2,3) must be set in case of 'null'?
Using 'dummy-objects' would mean, that your application must be able to deal with that, because it's not enough just to compare with 'null' ... or is it required that your application knows about those 'dummy'-objects? Must the application react different in case of 0,1,2,3?
If the application doesn't need to know about it, i wouldn't use the DummyObjects ... i would try to give my UserTypes all required information they need to determine what null-different value must be written to db ...

gtx
curio


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 15, 2004 7:29 am 
Expert
Expert

Joined: Thu Jan 29, 2004 2:31 am
Posts: 362
Location: Switzerland, Bern
Hi curio

Thanks for taking your time.

If your a fan of funny db designs: Waht about half foreign keys or denormalized historized data :-).

Unfortunately the business layer heavily depends on these values. If I get the chance to redesign the DB I'd create real data in a separate table and use joined-subclass to get real objects from hibernate.

This means the DummyObjects will be subclasses of the real referenced Class.

The goal of the whole DummyObject thing is that I don't have to change the business layer once I get the chance to change the DB without killing people.

HTH
Ernst


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 15, 2004 7:57 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Could you just do all the processing in a custom UserType? The UserType could still return your "domain objects". You would lose the ability to have Hibernate manage all the cascade stuff as well as the ability to perform outer-join loading. But UserType could definitely handle all this.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 15, 2004 8:50 am 
Expert
Expert

Joined: Tue Oct 05, 2004 9:45 am
Posts: 263
@ernst
no problem ... i've got in some cases similar problems ... so why not share thoughts ...

I've got some denormalized tables, too ... and some references sharing parts of the same fk :) ...

One thing i don't understand so far ... you have a property which will be set to 'null' in case of 0,1,2 and 3 in db for reading (this property is the fk for a many-to-one-relationship).
The Application needs to know what value is corrently in the db ... i could imagine something like this:

Code:
if (manyToOneRef instanceof DummyObject1) then ...

Your application only needs to know which value is in db and won't work with the DummyObject itself. Am i right with that? ... so why not use the property?
Return 'null' for the many-to-one and set the value 0...3 for the property.
Perhaps no setter-Method for this property, because the value will be set from the UserType at reading or from your domain-object during the set-call of the 'many-to-one' ...

If your Application works with those values, they have business-meaning .. if you sometimes change the keys, those values would be still needed ... so you can use this property ...

Or do i think in a wrong way?

gtx
curio


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 15, 2004 9:33 am 
Expert
Expert

Joined: Thu Jan 29, 2004 2:31 am
Posts: 362
Location: Switzerland, Bern
@curio
I think it works both ways.
If you only need to distinguish between oridnary references and the 1,2,3 case, soemthing like an enum is fine.
If you have more complicated decisions/behaviour depending on whether it's an 1,2,3 I'd like to put this into different subclasses.

In our business logic the 1,2,3 case and some more cases based on real data, are the haert of a complicated engine to historize data, so sublcassing (and some more GOV patterns) comes in handy.

@steve:
That sounds interesing. Do you mean I could replace the <many-to-one> with a <property ... type="i.know.how.to.deal.with.0.1.2.3">?

Yes I can see how this works. For reading the UserType simply returns the DummyObject, for writing it replaces the dummys with the apropriate foreign key.

Thanks a lot.
I'll give the i.know.how.to.deal.with.0.1.2.3 UserType a chance.
Ernst

BTW: Once more I learned a lot about hibernate in the user forum. I've to convice my boss that it's a good idea to waste some time in the forum every now and then.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 15, 2004 9:48 am 
Expert
Expert

Joined: Tue Oct 05, 2004 9:45 am
Posts: 263
ah now i understand ... i thought the hole time, that your many-to-one relationship either returns a DummyObject or a 'real' business-object ...

sorry! ... yes, steves idea is a really good choice!

gtx
curio

BTW: it would be great, if (e.g. in hibernate3) i could implement a UserType for many-to-one etc., too (not only for properties) ...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 19, 2004 11:16 am 
Expert
Expert

Joined: Thu Jan 29, 2004 2:31 am
Posts: 362
Location: Switzerland, Bern
@steve

I just had a closer look into the coding of such a user type. Unfortunately I either do not fully understand your idea or it does not work.

If I have a look at the nullSafeGet method:
Code:
   public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException;


I can easily create the DummyObject if necessary, but how can I load the real one. I need to do a Session.load(), but there isn't a session available here.
The real Objects do have all kind of relations to other persistent entities of the business logic. Saying that I think simply creating a Session will likely cause some StaleObjectExceptions if the business logic starts setting refernces which are loaded from diffrent sessions.

Any help is welcome.
TIA
Ernst


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 03, 2004 6:28 am 
Expert
Expert

Joined: Thu Jan 29, 2004 2:31 am
Posts: 362
Location: Switzerland, Bern
Since I did not find a better solution I implemented the solution mentioned in the first post.

But there was something missing:
Although the <many-to-one> property is marked as update and instert false. Hibernate trys to process my DummyObject up on flush. I solved this by writing a ClassPersister doing nothing for the DummyObjects. This means I've now a hbm.xml file for the DummyClass as if it would be a real persistent class.

Code:
<hibernate-mapping>
   <class
      name="ch.bedag.gba.cap.server.business.model.geschaeft.ErsterfassungsGeschaeftsfall"
      persister="ch.bedag.gba.cap.server.persistence.hibernate.dao.ErsterfassungsGfPersister" >
      <!-- Dummy PK declaration to kepp hiberante happy -->
      <id name="myPk" type="ch.bedag.gba.cap.server.persistence.hibernate.dao.BenutzerPkType" access="field">
         <column name="dummy1" sql-type="systemId" not-null="true"/>
         <column name="dummy2" sql-type="id" not-null="true"/>
         <generator class="ch.bedag.gba.cap.server.persistence.hibernate.CapiIdentifierGenerator"/>
      </id>
   </class>
</hibernate-mapping>


HTH
Ernst


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