Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Why is Hibernate setting all decimal points to zero in a BigDecimal?

 
Al Koch
Ranch Hand
Posts: 48
Eclipse IDE Firefox Browser Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

I am using Hibernate as my JPA provider and I have a "PRICE" column in a Sybase SQLAnywhere 16 database that is defied as decimal(19,4). The associated data is declared as:

I then load the data value with:


and then I use em.persist() to get the data written to the database. A new row is written to the database and, using a Sybase database "editor" app, I can see that String columns are correct but the Price column shows:
14276.0000

I have tried defining the database column as double and money and with double I get 14276 and with money I get 14276.0000.

Also, if I manually (using the Sybase database "editor" app) load PRICE with, say, 11257.6914 I can fetch the row using Hibernate and getBdPrice() returns the exact value of 11257.6914 so the problem only happens on a write.

Can someone tell me what is going wrong here? How do I get the decimal digits into the database?

Thank you.
 
Paul Clapham
Sheriff
Posts: 21572
33
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was thinking that the problem had something to do with calling setScale, rather than writing to the database, but when I read the API documentation (I always have to do that when I'm working with the scale of a BigDecimal number) I realized that your call to setScale doesn't actually do anything. If you read the documentation for the method then like I did, you should see why.

So that probably doesn't help with your problem; however I'd suggest examining the double value before writing it to the DB to make sure it hasn't been altered. You could also call "setScale(4, RoundingMode.UNNECESSARY)" to confirm that it's not you who is rounding to the nearest integer.
 
Al Koch
Ranch Hand
Posts: 48
Eclipse IDE Firefox Browser Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Paul,

Thanks for your reply. I have examined the BigDecimal variable's value right before the persist() (I used toString()) and all four digits are still there. I initially discovered the problem when I was not even using setScale() and it was only then that I tried using that! So, I don't think setScale() is the problem.

I am a bit confused when you said that the setScale() does nothing. I don't see anything in the docs to suggest my use has no effect. I am reading the JavaDoc doc that pops up in Eclipse. Are you referring to another doc? can you explain why you say this?

More importantly, do you have any other ideas why this is happening?

Thanks again!
 
H Paul
Ranch Hand
Posts: 471
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
(I could be off topic but it helps your discussion)

If it help:

While looking at 1 of thread where the discussion is about bike and tire. His bike does not have a price field.
I say why not include your bdPrice to see.





1. I added because I let Hibernate to create db schema for me.




2. With about code, there is NO issue in persisting the above value into the database I used HSQLDB
and no issue for reading back that value. Value stored in db is exactly as precision mentioned: 14276.5257
 
Paul Clapham
Sheriff
Posts: 21572
33
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Al Koch wrote:I am a bit confused when you said that the setScale() does nothing. I don't see anything in the docs to suggest my use has no effect. I am reading the JavaDoc doc that pops up in Eclipse. Are you referring to another doc? can you explain why you say this?


You didn't notice the paragraph starting with "Note that since BigDecimal objects are immutable, calls of this method do not result in the original object being modified..."? So yeah, the setScale() method does nothing but return a different object -- which your code ignores.

But as you suggest, that's a minor detail which is irrelevant to your database problem. And sorry, I have no suggestions about how to deal with that.
 
Dave Tolls
Ranch Hand
Posts: 2103
15
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Since Hibernate in general doesn't have this problem, that is I've not encountered it in other DBs, it's either a problem in the DB itself (unlikely) or the JDBC driver.

What driver are you using and what version?
 
Al Koch
Ranch Hand
Posts: 48
Eclipse IDE Firefox Browser Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Paul,

Thanks for clarifying your comment - yep, I missed "immutable" which was careless but unfortunately setScale() doesn't appear to be the problem here. Please see my follow on comment about Sybase code.
 
Al Koch
Ranch Hand
Posts: 48
Eclipse IDE Firefox Browser Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi H Paul,

Thanks for your code. I guess it shows that this works in your environment. Please see my follow on comment.
 
Al Koch
Ranch Hand
Posts: 48
Eclipse IDE Firefox Browser Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Dave,

I think you are right. I am using:
Sybase SQLAnywhere 16
jConnect4
SQLAnywhere16Dialect for the Hibernate dialect.

Any ideas about what's going wrong here?

Thanks.

 
H Paul
Ranch Hand
Posts: 471
4
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If I were you:

In waiting for the theorical explanation
or detail investigation
or help from any one who has the similar technical environment,
can you do 1 quick test: persist the object using JDBC to see how big decimal data is persisted?
 
Al Koch
Ranch Hand
Posts: 48
Eclipse IDE Firefox Browser Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi H Paul,

I apologize for the slow response - I am having to work several issues and cycle between them (based on the latest management priority!)

Thanks for you suggestion, but I have come to the conclusion that this is a bug in either the Sybase jConnect driver or the Sybase Hibernate code. It looks like the only solution is the rather ugly hack of declaring my entity attributes that really should be BigDecimal as String! That solves the problem and so I have to move on.

(Also, thanks for your continued help with the Hibernate Interceptor problem in the other post!)
 
Dave Tolls
Ranch Hand
Posts: 2103
15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Al Koch wrote:Thanks for you suggestion, but I have come to the conclusion that this is a bug in either the Sybase jConnect driver or the Sybase Hibernate code. It looks like the only solution is the rather ugly hack of declaring my entity attributes that really should be BigDecimal as String! That solves the problem and so I have to move on.


You should be able to test that quite easily, by removing Hibernate from the equation and simply saving something to a test table via JDBC.
But i know what you mean, time limitations etc etc.
And also, I expect, if it turns out to be the driver would you then have to jump through hoops to be allowed to use a different one.
 
Al Koch
Ranch Hand
Posts: 48
Eclipse IDE Firefox Browser Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Dave,

Thanks for the suggestion but as you said "gotta move on"! Plus, once I isolate where the bug is, tehn I would have to get SAP to do something about it!

 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic