How do I map a BigDecimal in Hibernate so I get back the same scale I put in?

In Java, new BigDecimal("1.0") != new BigDecimal("1.00") i.e., scale matters.

This is apparently not true for Hibernate/SQL Server, however. If I set the scale on a BigDecimal to a particular value, save the BigDecimal to the database via Hibernate and then re-inflate my object, I get back a BigDecimal with a different scale.

  • SQL Server 2012 error: object reference not set to an instance of an object
  • Programmatically Insert Rows Into Table
  • How to ALTER multiple columns at once in SQL Server
  • PreparedStatement executing successfully in oracle but throwing exception in Microsoft SQL
  • Trigger in SQL Server - Get the type of Transaction done for Audit Table
  • SQL Server: Multiple Output Clauses
  • For instance, a value of 1.00 is coming back as 1.000000, I assume because we’re mapping BigDecimals to a column defined as NUMERIC(19,6). I can’t just define the column as the required scale as I need to store both Dollar and Yen values (for example) in the same column. We need to represent the BigDecimals as numeric types in the database for the benefit of external reporting tools.

    Does there exist a Hibernate UserType which maps BigDecimal “properly”, or do I have to write my own?

    3 Solutions collect form web for “How do I map a BigDecimal in Hibernate so I get back the same scale I put in?”

    Just for informational sake, I can tell you that the creation of the BigDecimal coming back from the database is done by the proprietary JDBC driver’s implementation of the ‘getBigDecimal’ method of the database-specific ‘ResultSet’ sub-class.

    I found this out by stepping thru the Hibernate source code with a debugger, while trying to find the answer to my own question.

    I think this will work, I didn’t test it though.

    public class BigDecimalPOJO implements Serializable {
    
        private static final long serialVersionUID = 8172432157992700183L;
    
        private final int SCALE = 20;
        private final RoundingMode ROUNDING_MODE = RoundingMode.CEILING;
        private BigDecimal number;
    
        public BigDecimalPOJO() {
    
        }
    
        public BigDecimal getNumber() {
            return number.setScale(SCALE, ROUNDING_MODE);
        }
    
        public void setNumber(BigDecimal number) {
            this.number = number.setScale(SCALE, ROUNDING_MODE);
        }
    }
    

    Not sure, but you can check equality using a.compareTo(b) == 0.

    MS SQL Server is a Microsoft SQL Database product, include sql server standard, sql server management studio, sql server express and so on.