0

I am trying to store jscience physics amounts in my grails project. I am using hibernate and defaults, but I would prefer something with general applicability. I am specifically concerned with Mass and if I could have my way I would just make a line in the domain object like so:

MyDomainClass {
  Amount<Mass> weight
}

But that gives this error:

Caused by: org.hibernate.exception.DataException: could not insert: [project.MyDomainClass] at $Proxy10.saveOrUpdate(Unknown Source) ... 27 more Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'weight' at row 1 at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3601) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3535) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1989) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2150) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2626) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2119) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2415) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2333) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2318) at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) ... 28 more

I can fix that error by changing it to

def weight

Is there anything wrong with that, or a better way? Is there any database solution with advantages for dealing with mixed units? Googling this is so frustrating because everything is about unit testing.

Mikey
  • 4,692
  • 10
  • 45
  • 73

1 Answers1

1

You only hid the error messages with def weight - that made the field non-persistent. Since it's not typed, Grails and Hibernate don't know how to persist it and ignore it.

My guess is that it was storing the object as a blob and it was too big for the default size, but that's probably not what you want. Look at http://grails.org/doc/latest/guide/GORM.html#customHibernateTypes for how to map them in your domain class.

The link in the Grails doc to the Hibernate docs is broken - the correct url is http://docs.jboss.org/hibernate/stable/core/manual/en-US/html/mapping.html#mapping-types-custom

jScience may already have custom Hibernate types (either in the distro or from a 3rd-party) - you should check their docs.

Burt Beckwith
  • 75,342
  • 5
  • 143
  • 156
  • Burt, thanks for the help as always, but my app does seem to be persisting it as a def. I can do a save() and list() and then see it. – Mikey Jan 16 '12 at 01:51
  • 1
    Run `grails schema-export` with the type specified and again without to see the difference - the output will be in target/ddl.sql. – Burt Beckwith Jan 16 '12 at 02:28
  • Thanks again for that tip. Also, it seems I was wrong about it saving in the SQL despite the fact I can save it and get it back with list(). – Mikey Jan 16 '12 at 03:27
  • 1
    How are you doing this? You must be accessing cached data - are you doing this in a unit/integration test or from a running web app? If you're basing this on unit tests then you're seeing cached data in the in-memory hashmap that's pretending to be a database. In the running web app or in the Grails console save an instance, clear the session (`AnyDomainClass.withSession { it.clear() }`) and reload it and the non-typed data won't be there. Look in the database - it won't be there either. – Burt Beckwith Jan 16 '12 at 03:37
  • I am accepting your answer, but for the record defining hibernate types seems scary, so I'm just manually blobbing it and writing my own getters and setters which serialize the Amount and also store it converted to a standard unit as a BigDecimal to search on. – Mikey Jan 19 '12 at 08:21