Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 12 posts ] 
Author Message
 Post subject: How to map MySQL integer column value=0 to NULL value ?
PostPosted: Wed Jul 27, 2005 5:34 pm 
Beginner
Beginner

Joined: Wed Aug 27, 2003 3:46 am
Posts: 34
Location: Taiwan
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version:3.0.5

Mapping documents:
Code:
   <class name="Category">
      <id name="id" type="int">
         <column name="ID" not-null="true"/>
         <generator class="increment"/>
      </id>
      <many-to-one name="parent" column="ParentID" not-null="false" cascade="none" class="Category"/>
   </class>


Code between sessionFactory.openSession() and session.close():
Code:
    Category cat = (Category) s.load(Category.class , new Integer(1));
    System.out.println("cat id = " + cat.getId() + " , cat parent = " + cat.getParent());


Full stack trace of any exception that occurs:
Code:
Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [my.model.Category#0]
   at org.hibernate.ObjectNotFoundException.throwIfNull(ObjectNotFoundException.java:27)
   at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:118)
   at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:75)
   at org.hibernate.impl.SessionImpl.immediateLoad(SessionImpl.java:643)
   at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:59)
   at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:84)
   at org.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:134)


Name and version of the database you are using:MySQL 3.23

The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:


Hi , I think it is a general question.
Suppose a Category system , aCategory may have one/null parent and Set of children Category.
The ID is integer . In MySQL , default integer is '0' , not NULL
It will cause Hibernate tring to load a Category with non-existent row with id=0 and throw ObjectNotFoundException

How to solve it ?

Thank you in advanced.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 27, 2005 5:43 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
You can prove that Hibernate created a schema on MySQL that has a "default '0'" in it for the integer foreign key column? Then thats a bug.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 27, 2005 5:49 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
The solution is to use not-found="ignore", or write a UserType that transforms 0 -> null, and use that as the identifier type.

Of course Hibernate does not create schemas with default values.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 27, 2005 5:50 pm 
Expert
Expert

Joined: Thu Dec 04, 2003 12:36 pm
Posts: 275
Location: Bielefeld, Germany
By the way, in HQL you can use the function nullif(expr1, expr2).
If both expressions are equal, null is returned, otherwise the first expression.

Code:
from Clazz c where nullif(c.cat, 0) is null


Best regards
Sven


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 27, 2005 5:52 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Actually, the correct solution is to use two tables to separate two different entities: nodes and links. Anything else is a broken schema (the nullable foreign key is a good hint).


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 27, 2005 5:53 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
It's one of those things where "one-to-one on primary key using a link table" makes perfect sense. I'm currently rewriting the CaveatEmptor category tree example using this.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 27, 2005 6:07 pm 
Beginner
Beginner

Joined: Wed Aug 27, 2003 3:46 am
Posts: 34
Location: Taiwan
gavin wrote:
The solution is to use not-found="ignore", or write a UserType that transforms 0 -> null, and use that as the identifier type.

Of course Hibernate does not create schemas with default values.


Hi thank you for quick reply , after I set not-found="ignore" as follow :
Code:
<many-to-one name="parent" column="ParentID" not-null="false" cascade="none" class="Category" not-found="ignore"/>


But it throws different exception : PropertyAccessException
Code:
Hibernate: select category0_.ID as ID0_, category0_.uuid as uuid4_0_, category0_.name as name4_0_, category0_.description as descript4_4_0_, category0_.details as details4_0_, category0_.created as created4_0_, category0_.ParentID as ParentID4_0_ from Category category0_ where category0_.ID=?
INFO  - Error performing load command
org.hibernate.PropertyAccessException: Exception occurred inside setter of my.model.Category.parent
   at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:51)
   at org.hibernate.tuple.AbstractTuplizer.setPropertyValues(AbstractTuplizer.java:207)
   at org.hibernate.tuple.PojoTuplizer.setPropertyValues(PojoTuplizer.java:176)
   at org.hibernate.persister.entity.BasicEntityPersister.setPropertyValues(BasicEntityPersister.java:2919)
   at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:113)
   at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:530)
   at org.hibernate.loader.Loader.doQuery(Loader.java:436)
   at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:218)
   at org.hibernate.loader.Loader.loadEntity(Loader.java:1345)
   at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:116)
   at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:101)
   at org.hibernate.persister.entity.BasicEntityPersister.load(BasicEntityPersister.java:2471)
   at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:351)
   at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:332)
   at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:113)
   at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:75)
   at org.hibernate.impl.SessionImpl.immediateLoad(SessionImpl.java:643)
   at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:59)
   at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:84)
   at org.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:134)
   at my.model.Category$$EnhancerByCGLIB$$27c283f7.getParent(<generated>)
   at my.model.Test.main(Test.java:32)
Caused by: java.lang.reflect.InvocationTargetException
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:40)
   ... 21 more
Caused by: java.lang.NullPointerException
   at my.model.Category.setParent(Category.java:209)
   ... 26 more
Exception in thread "main" org.hibernate.PropertyAccessException: Exception occurred inside setter of my.model.Category.parent
   at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:51)
   at org.hibernate.tuple.AbstractTuplizer.setPropertyValues(AbstractTuplizer.java:207)
   at org.hibernate.tuple.PojoTuplizer.setPropertyValues(PojoTuplizer.java:176)
   at org.hibernate.persister.entity.BasicEntityPersister.setPropertyValues(BasicEntityPersister.java:2919)
   at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:113)
   at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:530)
   at org.hibernate.loader.Loader.doQuery(Loader.java:436)
   at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:218)
   at org.hibernate.loader.Loader.loadEntity(Loader.java:1345)
   at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:116)
   at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:101)
   at org.hibernate.persister.entity.BasicEntityPersister.load(BasicEntityPersister.java:2471)
   at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:351)
   at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:332)
   at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:113)
   at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:75)
   at org.hibernate.impl.SessionImpl.immediateLoad(SessionImpl.java:643)
   at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:59)
   at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:84)
   at org.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:134)
   at my.model.Category$$EnhancerByCGLIB$$27c283f7.getParent(<generated>)
   at my.model.Test.main(Test.java:32)
Caused by: java.lang.reflect.InvocationTargetException
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:40)
   ... 21 more
Caused by: java.lang.NullPointerException
   at my.model.Category.setParent(Category.java:209)
   ... 26 more



I hope it will print :
cat id = 1 , cat parent = null;

Maybe custom UserType will work , but I think it is too overkill...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 27, 2005 6:11 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
This exception is happening in *your* code, not in Hibernate.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 27, 2005 8:07 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Correction in case somebody finds this thread again: I was of course talking about a "one-to-many using a link table", in the case of a tree (not a network, that would be many-to-many). Still haven't found a good use case for one-to-one with a link table.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 27, 2005 8:11 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Think of the problem of assigning Desks to People where a Person can only be assigned one Desk at a time, a Desk can only be assigned to one Person at a time, but where it is utterly reasonable that a Person might not have a Desk, and a Desk might not have a Person.

This is a usecase of one-to-one on a link table.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 27, 2005 9:27 pm 
Beginner
Beginner

Joined: Wed Aug 27, 2003 3:46 am
Posts: 34
Location: Taiwan
gavin wrote:
This exception is happening in *your* code, not in Hibernate.

thank you
It's really my code's problem
solved.
Thanks again


Top
 Profile  
 
 Post subject: PojoTuplizer
PostPosted: Sat Jul 12, 2008 10:39 am 
Newbie

Joined: Sat Jul 12, 2008 10:16 am
Posts: 1
How can we use PojoTuplizer ? Anyone ahving sample program. What i need is customised implementation of hibernate Pojos so that hibernate sets and gets the Pojos that i create.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 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.