-->
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.  [ 15 posts ] 
Author Message
 Post subject: hibernate wants to save null values for my primitive types.
PostPosted: Thu Jan 22, 2009 8:03 am 
Newbie

Joined: Wed Jan 21, 2009 4:26 pm
Posts: 12
Hi guys

I struggeling a couple of days with it and I do not understand it.
Hibernate tries to set null values for my primitive datatypes in my entity class.
I noticed it, as I was trying to make the Trip class persistent. (saving Trip through session.save())!!!
I´m wondering why Hibernate can not manage to save this primitive values without trying to set them to null ?!
I`ve read that you have to use java object types e.g. Short, Integer, Boolean instead of short, int, bool.

Is that true?!

I´m using MySQL 5 and did mark some columns as default. For instance brandNew default 0 and hoursePower default 0 !!!

Any hints would be very appreciated. Thanks in advance.


My java class looks like:

class Trip {
private Car rentedCar;
.....
//setter and getter
}

class Car {
private boolean brandNew;
private short hoursePower;
//setter and getter
}

My mapping looks as follows:

<hibernate-mapping default-access="field" default-lazy="false" package="com.xxx.Trip">
<class name="Trip" table="Trip"
<id name="id" column="TRIP_ID" type="int">
<generator class="identity" />
</id>

<component name="rentedCar" class="com.xxx.Car">
<property name="brandNew" type="boolean"/>

<property name="hoursePower" type="short" />
</component>
</class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 8:17 am 
Newbie

Joined: Tue Jan 13, 2009 11:49 am
Posts: 11
but you do have an attribute with name "id" of type "int" in both classes? Sorry, just guessing. Maybe they are part of the "...".

dirk


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 8:29 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Quote:
Hibernate tries to set null values for my primitive datatypes in my entity class.
....
I`ve read that you have to use java object types e.g. Short, Integer, Boolean instead of short, int, bool.


If you want to use primitive type you should use short, int, float, etc, and not the corresponing object types. Primitive types can never be null, but objects types will be null unless you initialise them to some value. Example:

Code:
// The value is 0 by default
public int getValue()
{
  return value;
}
public void setValue(int value)
{
  this.value = value;
}

// The value is 'null' by default
public Integer getOtherValue()
{
  return otherValue;
}
public void setOtherValue(Integer otherValue)
{
  this.otherValue = otherValue;
}


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 8:43 am 
Newbie

Joined: Fri Jan 09, 2009 8:26 am
Posts: 3
Incase you are using Java5, just change primitive types of your bean to Wrapper classes and you don't need to change anywhere in the code.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 9:01 am 
Newbie

Joined: Wed Jan 21, 2009 4:26 pm
Posts: 12
And that´s exactly my problem I´m using primitve types as following

// The value is 0 by default
private int myPrimitiveType;

public int getMyPrimitiveType
{
return myPrimitiveType;
}
public void setMyPrimitiveType(int myPrimitiveType)
{
this.myPrimitiveType = myPrimitiveType;
}

But hibernate wants to set a null for my myPrimitiveType!
The exception is:
can not assinged to set a null value for myPrimitiveType

In my database MySQL the attributes looks like:
myPrimitiveType integer default 0,

Is that because I´m using in my mapping file a component within my entity?

Thanks again for ur help

P.s. I was reading some day, that somebody suggested to use object types instead of primitive types...
But why would that simple thing cause such troubles?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 9:07 am 
Expert
Expert

Joined: Thu Jan 08, 2009 6:16 am
Posts: 661
Location: Germany
I think it is because you have rows in your database, where myPrimitiveType's column contains null. Maybe this is data, which was added without default value. You don't have a not null constraint on this column, so it is possible. Have a look at the data in your tables. ;-)

_________________
-----------------
Need advanced help? http://www.viada.eu


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 9:09 am 
Expert
Expert

Joined: Thu Jan 08, 2009 6:16 am
Posts: 661
Location: Germany
I think it is because you have rows in your database, where myPrimitiveType's column contains null. Maybe this is data, which was added without default value. You don't have a not null constraint on this column, so it is possible. Have a look at the data in your tables. ;-)

_________________
-----------------
Need advanced help? http://www.viada.eu


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 9:10 am 
Expert
Expert

Joined: Thu Jan 08, 2009 6:16 am
Posts: 661
Location: Germany
To make it clear: I think the problem is the other way round: hibernate is not inserting null values to the db, but reading null values and trying to assign them to your primitive java types, which is not possible.

_________________
-----------------
Need advanced help? http://www.viada.eu


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 9:15 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Quote:
But hibernate wants to set a null for my myPrimitiveType!
The exception is:
can not assinged to set a null value for myPrimitiveType


Ok... can this be because you have rows which has a null value in this column in the database? The quoted error message seems a bit "strange". Is it really the exact error message produced by Hibernate? Can you also post the complete stack trace?

In any case, if there are null values in the database, you either have to (manually) change those values to some real value (eg. 0) or you have to change your code to use the corresponding object types instead.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 10:26 am 
Newbie

Joined: Wed Jan 21, 2009 4:26 pm
Posts: 12
@nordborg: using object types does not fit my requirements.
I want stay with my simple primitive types.

What I noticed is:
If I save the entity Trip with its Car that would be saved in db.
Unfortunately not correct because the attributes which supposed to be set to 0 are set to null.

So my column horsePower has a value {null} in my table.
And a further call gives me the stack trace below. (see stack-trace)

If I make an insert-statement manually through plain sql, my db mySQL is realizing it which sets the default values to 0 :).

Furthermore I tested the following: I marked the columns in XML-mapping file as "insert='false'" and it worked!!!
But is that my solution ??? It´s really confused ...


Caused by: org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of xxx.Trip.Car.hoursePower
at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:83)
at org.hibernate.tuple.component.AbstractComponentTuplizer.setPropertyValues(AbstractComponentTuplizer.java:81)
at org.hibernate.tuple.component.PojoComponentTuplizer.setPropertyValues(PojoComponentTuplizer.java:95)
at org.hibernate.type.ComponentType.setPropertyValues(ComponentType.java:358)
at org.hibernate.type.ComponentType.resolve(ComponentType.java:586)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:120)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:854)
at org.hibernate.loader.Loader.doQuery(Loader.java:729)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1860)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:42)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3049)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:399)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:375)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:139)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:179)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:103)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:846)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:557)
at org.hibernate.type.EntityType.resolve(EntityType.java:379)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:120)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:854)
at org.hibernate.loader.Loader.doQuery(Loader.java:729)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.doList(Loader.java:2213)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
at org.hibernate.loader.Loader.list(Loader.java:2099)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:94)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1569)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
at org.hibernate.impl.CriteriaImpl.uniqueResult(CriteriaImpl.java:305)
at xxx.MyDao$4.doInHibernate(MyDao.java:139)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:339)

Caused by: java.lang.IllegalArgumentException: Can not set short field xxx.Trip.Car.hoursePower to null value
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeShortFieldAccessorImpl.set(Unknown Source)
at java.lang.reflect.Field.set(Unknown Source)
at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:79)
... 98 more


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 12:58 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Quote:
I want stay with my simple primitive types.


So, then you must make sure that null values don't get into the database.
Have you tried to declare the database columns as "NOT NULL" to find out where this happens? I guess that you somewhere is saving a Trip that has no Car attribute. But... in this case Hibernate should not try to create a Car object when reading the Trip back from the database either...

Quote:
If I make an insert-statement manually through plain sql, my db mySQL is realizing it which sets the default values to 0 :).


Hibernate doesn't "use" the default values declared in the database. Hibernate always uses a complete insert statement with all columns.

Quote:
Furthermore I tested the following: I marked the columns in XML-mapping file as "insert='false'" and it worked!!!
But is that my solution ?


I guess not, because now Hibernate will never insert a value for it.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 2:01 pm 
Newbie

Joined: Wed Jan 21, 2009 4:26 pm
Posts: 12
So, then you must make sure that null values don't get into the database.
Have you tried to declare the database columns as "NOT NULL" to find out where this happens? I guess that you somewhere is saving a Trip that has no Car attribute. But... in this case Hibernate should not try to create a Car object when reading the Trip back from the database either...



It would be not clean, to set manually every time default values for my entity.
Yes, I tried it. And my result is that I get a another exception:
com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Column horsePower cannot be null.
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:931)
....




Hibernate doesn't "use" the default values declared in the database. Hibernate always uses a complete insert statement with all columns.

Ok fine. But why does the mapping provide me a default xml-tag, which seems that it doesn`t work either if I set it.

I agree with your last sentence, that hibernate tries to use a complete insert statement with all columns. And maybe that is the point. Hibernate sets by default values to null if no are provided during the insert process.



I guess not, because now Hibernate will never insert a value for it.
Yeah, you`right.


Thanks for ur help, I appreciate it :)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 2:35 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Quote:
Yes, I tried it. And my result is that I get a another exception:


That was expected. I suggested it as a way of finding the place were you are saving the problematic Trip that generates null values.

Quote:
Ok fine. But why does the mapping provide me a default xml-tag...


It is used by the schema-generation tool, which is not really part of the inner core of Hibernate. See http://www.hibernate.org/hib_docs/v3/re ... guide-s1-2

There are several other attributes here that the Hibernate core doesn't care about. For example, check, unique and length constraints. I think it is only the not-null constraint that Hibernate cares about.

There is another option but it is more advanced and it is usually used with legacy database schemes that has a 0 instead of null in the database and were it is complicated to change the database schema to allow null values.
The same technique can probably be used in your case. See this post http://forum.hibernate.org/viewtopic.php?t=993722 for more information.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 3:35 pm 
Newbie

Joined: Wed Jan 21, 2009 4:26 pm
Posts: 12
oh not again such a Hobson´s choice thing.

so u gonna tell me that even I use the object types of java or I build my own hibernate data type...

unbelievable ...

don´t you know why hibernate is acting this way? Is there a human explanation ???

Thanks again for your great help :)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 22, 2009 5:17 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Quote:
don´t you know why hibernate is acting this way?


But the Trip.rentedCar object is null, isn't it? I don't think Hibernate should "guess" that this really means 0, because in most cases it doesn't.

Personally I think that if a database allow null values in a column, you should use the object variants of the primitive types. If you absolutely need to use the primitive types, your columns should be NOT NULL, and your code should make sure that everything is initialized to proper values.

I just noticed that there is another thread (http://forum.hibernate.org/viewtopic.php?t=993972) discussing a very similar issue, which may mean that the second option is hard to implement with components.

The option with a custom user type should be used only as a last resort and only if it is "politically" inconvenient to use one of the other options.


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