-->
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.  [ 12 posts ] 
Author Message
 Post subject: Relationship foreign key uses '0' instead of null
PostPosted: Sat Aug 21, 2004 9:44 pm 
Newbie

Joined: Tue Aug 10, 2004 3:20 pm
Posts: 11
I am having a mapping problem. I am mapping to an existing database whose schema would probably take an act of God to change. In this database all primary keys are integer values. In a one-to-many relationship between two tables, instead of making the foreign key null when the relationship does not exist, the programmer sets the foreign key field to '0' instead.

Is there a way to map the many side ( in the <many-to-one...> tag) to say that '0' means there is no related record instead of null?

Any help greatly appreciated.

_________________
Sincerely,
James.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 22, 2004 12:22 am 
Newbie

Joined: Mon Aug 09, 2004 4:28 am
Posts: 18
Location: Australia
James,

I am not entirely sure of all the problems that you are encountering .....

Have you looked at defining your own UserType.

This UserType could map a null in your java class to a 0 when writing to the database and vice versa when reading.

If you have a look at the topic "Handling Dates in a Legacy System" (in the forum) you will see the fun and games I have had trying to cope with an empty string representing Null in a date field.

Fortunately, I do not think your problems are nearly so bad .......

You would need to modify the sqlTypes to integer:


Code:
public int[] sqlTypes() {
  return new int[] { Types.INTEGER };
}



You would also have to modify the nullSafeGet() and nullSafeSet():


Code:
 
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
  integer val = rs.getInteger(names[0]);
 
  if (null == val)
    return(null);

  if (val == 0)
    return(null);
        
     return val;
}


You would have to do the reverse for the nullSafeSet (I have not included the code as I would probably get it wrong first time !!!!!)

I do not think that you would have to alter deepCopy as it appears to use nullSafeGet and hence a 0 would already been changed to a Null.

Obviously you would have to later your table mapping to use the newly created UserType.

Hope this helps,

Mike.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 22, 2004 3:49 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
Quote:
instead of making the foreign key null when the relationship does not exist, the programmer sets the foreign key field to '0' instead.


why? is he using int? if yes just change it to Integer

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 22, 2004 2:33 pm 
Newbie

Joined: Tue Aug 10, 2004 3:20 pm
Posts: 11
anthony wrote:
Quote:
instead of making the foreign key null when the relationship does not exist, the programmer sets the foreign key field to '0' instead.


why? is he using int? if yes just change it to Integer


The legacy system is programmed that way... not my Hibernate classes. Something I don't have control over. Also that database was defined to not allow null in the foreign key field. I suspect that the relationship was required at first, but the requirement was relaxed and implemented in such a way so that the db schema didn't have to change.

Pretty lame, but that is what I have to live with.

_________________
Sincerely,
James.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 22, 2004 3:00 pm 
Newbie

Joined: Tue Aug 10, 2004 3:20 pm
Posts: 11
Mike Canham wrote:
Have you looked at defining your own UserType.

This UserType could map a null in your java class to a 0 when writing to the database and vice versa when reading.


Hey, Mike, thanks for the reply. It seems that what we are trying to is a little different. I am trying to map an association between entities where as the UserType is meant to map between java values and db values (correct me if I am wrong).

I think something like the following would be what I am looking for (note the null-value attribute):

Code:
        <many-to-one
            name="qaContact"
            class="com.couball.bugs.data.User"
            cascade="none"
            outer-join="auto"
            update="true"
            insert="true"
            column="qa_contact"
            not-null="true"
            null-value="0"           
        />


This means that this class has a many-to-one relationship to the User class as defined by the qa_contact field. The database field is not nullable because of not-null="true" attribute. However, a value of "0" acts as a null to indicate that there is no qaContact for this instance because of the null-value="0" attribute.

In the java object itself, the object reference probably be set to null. The mapping would be to map a null java object reference to '0' in foreign key field in the database and vice-versa.

Is something like that possible?

Sincerely,
James.

_________________
Sincerely,
James.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 22, 2004 3:10 pm 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
No, this is not possible.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 22, 2004 4:21 pm 
Newbie

Joined: Tue Aug 10, 2004 3:20 pm
Posts: 11
michael wrote:
No, this is not possible.


Ah... hmmm.

Can you help me understand if something like that is even a good idea to suggest as an enhancement? I know that the implementation of the legacy application is broken, but I'd have an easier time hacking the change to hibernate myself or at least suggesting the enhancement and having someone who knows better do it.

If not, could you suggest a work around? The way I'd think to do it is to treat the foreign key field as a value and just have normal getters and setters rather than define a hibernate association.

Any and all help appreciated.

_________________
Sincerely,
James.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 22, 2004 4:22 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
The workaround is to fix your database.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 22, 2004 4:43 pm 
Newbie

Joined: Tue Aug 10, 2004 3:20 pm
Posts: 11
christian wrote:
The workaround is to fix your database.


You guys are fast... thanks for the reply... I'll see what I can do from that side.

_________________
Sincerely,
James.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 22, 2004 4:59 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Actually, I think it might be possible. A MAnyToOneType wraps around the identifier Type. So if you wrote a custom type that mapped null->zero and used it as the identifier type of the associated class, then the many-to-one would see that.

I havn't actually ever tried this, but don't immediately see a reason why it would not work. Obviously, HQL expressions like "foo.bar is null" would need to be rewritten as "foo.bar = 0", but that is a minor point.

Of course, "fix the database" is an even better solution.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 22, 2004 6:47 pm 
Newbie

Joined: Mon Aug 09, 2004 4:28 am
Posts: 18
Location: Australia
James,

I think Gavin is saying the same thing as me ......

What I was trying to do, was make the field a null in Java / Hibernate land, but remain as a zero in the database column .....

Gavin, has said that he thinks that the HQL wraps around the user type ....

So using the UserType as I suggested, might work .......

I also know where you are coming from, as I am trying to interact to a legacy database system, which still has a running application ..... so making changes to it, is not as easy as everyone wants to suggest ....

Good Luck,

Mike.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 25, 2006 8:27 pm 
Beginner
Beginner

Joined: Wed Oct 05, 2005 5:35 am
Posts: 47
Location: France
gavin wrote:
Actually, I think it might be possible. A MAnyToOneType wraps around the identifier Type. So if you wrote a custom type that mapped null->zero and used it as the identifier type of the associated class, then the many-to-one would see that.


Just for the record: yep, a custom Type like Gavin suggests works pretty well.

Thanks!


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