-->
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.  [ 11 posts ] 
Author Message
 Post subject: Default for nulls in many-to-one mapping
PostPosted: Mon Nov 12, 2007 3:50 pm 
Newbie

Joined: Mon Oct 15, 2007 3:18 pm
Posts: 15
I want to default a null many to one mapping to some useful value. That is, the foreign key is null, and its value in the enclosing object is null. E.g., where issue and contact are tables, and issue has a nullable foreign key to a contact and Contact and Issue are the ORM classes:

Class Issue {
...
Contact assignedTo;
...
}


Class Contact {
Long contactId;
...
String lastName;
...
}

when Issue is instantiated assignedTo is null if the underlying fkey is null. I want to default it a non-null value which will mean unassigned. I'm writing a JSP which will show a list of contacts, one of which can be assigned this issue (populating a select list with the contact names and their id values). If assignedTo is null the page bombs (using Spring <form:select path="assignedTo.contactId">)

I am looking at CompositeUserType, but am puzzled by what goes into the outgoing stmt on NullSafeSet. I am also puzzled at how the default is assigned; what should the type (in this case) of Issue.assignedTo be?

Is this the right path? This is doubtless not a new problem, and there is probably a good example lying around somewhere. Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 12, 2007 4:01 pm 
Newbie

Joined: Mon Oct 15, 2007 3:18 pm
Posts: 15
Am I outsmarting myself here? Is this as simple as newing an object in the default constructor, or will it be overwritten with null anyway? Stay tuned....


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 12, 2007 4:39 pm 
Newbie

Joined: Mon Oct 15, 2007 3:18 pm
Posts: 15
Newing an object in the default constructor does not work. That is,

Class Issue {

...
Contact assignedTo ;
...

public Issue() {
...
assignedTo = new Contact() ;
...
}
}

still results in null assignedTo if the foreign key contained in that column in the table is null. I suppose Hibernate is enforcing the ORM I have defined. How then do I indicate a non-null but non-assigned value so the code works? There don't seem to be any useful annotations for this case. Is a custom UserType the only way to go? This should not be so difficult; it seems a violation of POJO principles.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 12, 2007 4:51 pm 
Newbie

Joined: Mon Oct 15, 2007 3:18 pm
Posts: 15
Changing the setter method to assign a default when the parameter value is null doesn't work either. The framework catches it as "unsaved transient". I suppose I could make the whole object transient but that probably leads to other difficulties.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 12, 2007 5:09 pm 
Newbie

Joined: Mon Oct 15, 2007 3:18 pm
Posts: 15
Setting FlushMode.MANUAL and removing tx.commit() lets me assign the default in the setter. The real problem here is that the unassigned value is not in the database; Hib would probably throw on persisting, same with a default type holding that unassigned value. The only real solution is to put the unassigned value there, and set nullable=false on the mapping.

Thinking out loud...


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 13, 2007 4:43 pm 
Newbie

Joined: Mon Oct 15, 2007 3:18 pm
Posts: 15
On further reflection I think this is a problem in Hibernate (feature, not bug). It's really a common and trivial situation. I have a null many to one value. Hibernate loads it as null object. When I use it for screen display the JSP blows up with null ptr. There should be some convenient way to default a non-assigned value for the null, so the JSP doesn't blow. There should also be a convenient way of not persisting the unassigned value back to the database, where it would cause a foreign key exception in the table it points to. This could be indicated in annotations and implemented by the framework. As it stands, Hibernate is imposing the ORM into the web page, which is far too rigid.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 13, 2007 5:16 pm 
Newbie

Joined: Mon Oct 15, 2007 3:18 pm
Posts: 15
Of course this would probably have consequences throughout, distinguishing betw usable but unassigned values (not present in the database) and nulls. But the POJO principle would seem to require it. In this case the POJO is being used by another framework, which depends on it being usable, not partly nulled out to reflect the object-relational mapping.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 14, 2007 10:31 am 
Newbie

Joined: Mon Oct 15, 2007 3:18 pm
Posts: 15
The only way to deal with this is to use a custom type for mapping. I actually tried this before, got confused betw my POJO and the custom type, which does not replace the POJO, is used only by the framework to get values in and out of the POJO. Here is a link with some good examples of this problem. http://www.i-proving.ca/space/Technolog ... +Hibernate

Note their use of the custom mapper to map the key field for the POJO, not to map the POJO itself.

I still think this is a long way around the barn to solve a common problem in legacy databases. Hibernate could allow the option of assigning a value from the default constructor for a null object when loading, and of not writing such values when saving. The POJO would be usable by other frameworks (like Spring, for web display), but empty, with the application taking responsibility for recognizing a value not in the database, standing in for a null.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 14, 2007 7:01 pm 
Pro
Pro

Joined: Tue Aug 26, 2003 8:07 pm
Posts: 229
Location: Brisbane, Australia
Just to break into this little soliloquy here :)

I too have a similar problem.

I'm trying to read from a crazy legacy schema where a particular value in the foreign key column (0), really means null. There is no "0 row" in the other table and it's causing no end of problems with loading and querying.

Any suggestions besides the custom type one (which I will try anyway - we're also going to try adding a view that unions in the "0 row").

_________________
Cheers,
Shorn.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 15, 2007 7:36 am 
Newbie

Joined: Mon Oct 15, 2007 3:18 pm
Posts: 15
I think the link in my prev response shows the answer to your problem using the custom mapper. They had a char field that was all blank, standing in for null. Their mapper returned null if the field was blank. And did something sensible on the set.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 16, 2007 2:01 pm 
Newbie

Joined: Mon Oct 15, 2007 3:18 pm
Posts: 15
There is no satisfactory way to deal with this in Hibernate. Use of the custom mapping type means essentially repeating the POJO, exposing all the properties in the custom mapper. Other possibilities like interceptors or filters or event listeners felt equally kludgy. So it belongs elsewhere, like in the web framework for a web app. In fact there is a perfectly natural place in Spring, on the FormAction createObject. I check for null entity objects in the class I'm reading in for editing, and set them to an unassigned (non null) value. On the persist side these special entities may be ignored automatically by Hibernate, because they are transient, being created with new. Or I may have to null them out with custom binding/property editing. Have yet to figure this out. The real trick is making this generic, so I don't have lists of entity classes requiring special treatment all over the app. It should be possible to add a new entity to the entity I'm editing, and have it treated this way automatically.


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