Not-null property references a null or transient value
June 5, 2008
Context:
Trying to run an application (using spring & hibernate) that has a parent (one) and child (many) relationship. When trying to add a parent, children maybe added at runtime and once submit is pressed both the parent and the respective children are saved.
To add the children at run time isFormChangeRequest & onFormChange methods, provided by spring, are used. And when submitting the parent form, hibernate helps to save the children automatically when the parent is saved.
The following is an excerpt of what the mapping looks like…
<set name="children" inverse="true" cascade="all-delete-orphan">
<key column="PARENT_ID" not-null="true"/>
<one-to-many class="Child"/>
</set>
Problem:
After submit is pressed, the following creeps up….
org.springframework.dao.PropertyValueException: not-null property references a null or transient value:...
It seems like one of the child properties is missing, but a simple System.out.print shows that the property being complained about is NOT null !
Solution:
The problem was to do with hibernate not “automatically” being able to store the child to the db (although the information was saved in memory)….. because the relationship between the parent and the child had not properly been set up. So although the hibernate mapping was fine, it was not being applied because the parent-child relationship was faulty.
[Please note, that there could be several solutions to this problem, rather than try and list all of them here... I thought it best to try and explain the CONCEPT behind the solution.]
Examples:
So like I said above, the problem is to do with a faulty parent-child relationship… it may not necessarily be to do with the hibernate mapping file. It could be many other things like the addChild() method not being written properly in the FooParent.java, or perhaps missing the part which adds the newly created child to the parent… so although the child is being created it is not being properly added to the parent and hence being confronted with a message that indicates a transient (meaning temporary) value or object that has been created but not properly saved.
So let me repeat again, in order to solve this problem, you need to check all the parent-child code (especially the add & edit controllers) and ensure that after the child is created it is being added to the parent and then being saved.
For example, instead of….
child.setParent(parent); getSession().save(child);
also add, one other line …
parent.getChildren().add(child); child.setParent(parent); getSession().save(child);
… Wa Allahu A’lam.
Other References:
Entry Filed under: Hibernate, Spring. Tags: cascade="all-delete-orphan", Hibernate + cascade="all-delete-orphan", not-null property references a null or transient value, org.hibernate.PropertyValueException: not-null property, org.springframework.dao.PropertyValueException, spring + hibernate + not-null property references a nul, spring + hibernate + parent child relationship, spring + hibernate + PropertyValueException, Spring + isFormChangeRequest + onFormChange.
11 Comments Add your own
Leave a Comment
Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed
1.
robert | November 9, 2008 at 12:09 am
Please can u show example of a solution
2.
ibnaziz | January 21, 2009 at 9:46 am
I have edited the post… and provided one possible solution. I hope that helps.
3.
Puneet Swarup | February 12, 2009 at 10:53 pm
Thanx for that, i do have some different problem, hope u help me out in this too.
I have a whole object graph with a parent, its childs, and sub-childs.
When i try to save the parent (Hibernate should persist all the children also) the children records are saved first and lastly the parent record [spelling corrected by mod] is saved; But the problem is that relationship is not established in between parent-child. The child records are not updated with parent id and they appear orphan in db.
Next time if i try to retrieve object graph by fetching parent, no children are fetched as foreign key of parent is not present in child records.
Thanx in advance.
4.
ibnaziz | February 13, 2009 at 11:33 am
Hi Puneet,
Thanks for the comment. Regarding your problem, I have to say that it is a bit difficult to try and pinpoint the problem without having a look at the code first. Also it depends on the type of relationship you are trying to establish; unidirectional or bidirectional. Assuming that you are after a BIDIRECTIONAL relationship… try and ensure the following things are properly set/coded…
1) … the parent’s hibernate mapping file, especially the part describing the children….
i.e.
<set name="childItems" cascade="all-delete-orphan"><key column="PARENT_ID" not-null="true"/>
<one-to-many class="ChildItem"/>
</set>
please note that the above code is also assuming that children are being added through the parent, since cascade=all-delete-orphan has been specified. So WHILE creating a parent, children are also added. But if you would like to create the parent first without adding the children and only add the children after the parent has already been created… then you DON’T need the cascading instead you need to specify here inverse=true to tell hibernate that the parent should be updated through the child.
2)… the child’s hibernate mapping file, especially the part describing the parent…
i.e.
<many-to-one name="parent" column="PARENT_ID" class="Parent" not-null="true"/>please note that this is the part that will help you hold the parent’s id !!
3)… the child’s db table… to check that a column has been created for storing the parent’s id
4) … and also the java code to ensure that when creating/adding the child the parent’s reference is also added as follows…
child.setParent(parent);… hopefully… if all the above-mentioned points are properly set.. things should start rolling as normal.
Take care….
5.
Puneet Swarup | February 13, 2009 at 1:22 pm
Hi,
Thanks again for your quick reply.
I am attaching my code.
The following is the code for parent, where i eagerly fetch the child relations and save / update the children through the parent.
@OneToMany(mappedBy = "parent", cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
public Set getChild() {
return childt;
}
the following is child code. As i dont want child record to update parent i have not specified any cascade (i believe by default its no cascade)
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "PARENT_ID")
public Parent getParent() {
return parent;
}
Now in above when i persist the parent with set of childrens, all records are persisted but the child records dont have the parent id, bottomline relation between parent and child is not established.
Please suggest.
6.
Puneet Swarup | February 16, 2009 at 1:30 pm
HI,
I was expecting some quick help from you. Can you please look into above code snippet and tell me where am i going wrong.
Thanks in advance.
7.
ibnaziz | February 17, 2009 at 11:10 am
I am sorry puneet. I have some time constraints despite my wish to help you further…. and comments of the following nature….
>> I was expecting some quick help from you.
…. aren’t too helpful. So although I can’t promise anything as “quick” as you would like me to…. I might be able to have a look at it in the future some time.
best regards.
8.
Puneet Swarup | February 17, 2009 at 12:50 pm
Hi,
i didn’t mean any offence. I am sorry if i have done so in any manner.
Thanks & regards.
9.
maheshadikte | August 29, 2009 at 8:44 pm
hi,
plz provide the implementation of isformchangerequest() and onfromchange() with an example ,we r desply in need of it
10.
ibnaziz | August 31, 2009 at 11:25 am
@Maheshadikte,
I am sorry for the delay.. but I have a tight schedule… anyway…. since you have been desperately asking for an example.. I will try to informally and quickly give one here…..
——————————
JSP
——————————
...<input type="submit" name='addOrderItem' value="addChild" />...——————————
ChildFormController.java
——————————
...public class ChildFormController extends SimpleFormController implements InitializingBean
{
...
/**
* This method is invoked to see if the form command has been modified (without the need for final submission)
*/
@Override
protected boolean isFormChangeRequest(HttpServletRequest request)
{
// return true if the addChild is not null
return ( request.getParameter( "addChild" ) != null );
}
/**
* This method is invoked if the 'isFormChangeRequest' returns true
*/
@Override
protected synchronized void onFormChange(HttpServletRequest request, HttpServletResponse response, Object command) throws Exception
{
Child child = ( Child ) command;
if( request.getParameter( "addChild" ) != null )
{
// add a new child item
...
}
...
}
...
}
… I hope this simple example is of help to you….
regards,
ibn aziz
11.
maheshadikte | October 15, 2009 at 12:31 pm
its helps a lot,
tks
mahes