Turn off Decimal128 support in GORM when working with MongoDB 3.2
- 2 minutes read - 388 wordsGot GORM 6.1 (Grails 3.3+ or Micronaut), MongoDB 3.2 and strange “Prematurely reached end of stream” errors?
- Check if these happen when trying to save BigDecimal fields and disable it in grails.mongodb.decimalType: false
“Premature end of stream” with MongoDB 3.2
I got to get acquainted with Grails framework about a year ago. It is a fantastic framework with lots of goodies that is unfortunately not too popular nowadays and sometimes finding help isn’t easy, hopefully that will change now that Grails 4 got released). One of the most impressive parts of Grails is GORM - it’s data access toolkit (which is available also separately from grails) that allows you for things like
book = Book.findByTitleLikeOrReleaseDateLessThan("%Something%", someDate)
Lately we were upgrading from Grails 3.2 to Grails 3.3 that also means upgrading GORM from 6.0 to 6.1 and exactly in GORM-MongoDB-related part of the app got stuck with errors like.
Exception in thread "main" com.mongodb.MongoSocketReadException: Prematurely reached end of stream
at com.mongodb.connection.SocketStream.read(SocketStream.java:88)
at com.mongodb.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:494)
at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:224)
at com.mongodb.connection.UsageTrackingInternalConnection.receiveMessage(UsageTrackingInternalConnection.java:96)
at com.mongodb.connection.DefaultConnectionPool$PooledConnection.receiveMessage(DefaultConnectionPool.java:440)
at com.mongodb.connection.WriteCommandProtocol.receiveMessage(WriteCommandProtocol.java:262)
BigDecimals are not supported by MongoDB 3.2 so you’ve got to avoid them
Further investigation showed that error was happening when we tried saving an object with BigDecimal field inside. GORM 6.0 works with MongoDB Java driver 3.2 for MongoDB 3.2 that doesn’t have native type for big decimals, so GORM automagically converts it to String that is not ideal but works unless you need to perform queries based on mathematical value of this field. GORM 6.1 works with Java Driver 3.4 for MongoDB 3.4. MongoDB 3.4 got native support for big decimals, so GORM is trying to use it. That works perfectly unless your database is still MongoDB 3.2 that has no idea about big decimals and spits a rejection with such logs on the DB side:
[conn50774] Assertion: 10307:Client Error: bad object in message:
Attempt to use a decimal BSON type when experimental decimal server support is not currently enabled.
If you happen to stumble at the same issue and you are not fond of creating your own converters from Groovy/Java to Mongo’s BSONs!!link, you can disable the big decimal support in your application.yml as in
grails:
mongodb:
decimalType: false
Hopefully this info saves some hours of debugging it took me to get to the code that decides on how to convert which data type.