The problem is org.hibernate.mapping.Column has a very poor processing of DataTypes from hibernate files and liquibase is completely based on this class.
I put examples:
]hibernate datatypes from files | | | sql type code from mapping.Column | | | length, precision, scale from mapping.Column | | | salved typeName in liquibase.database.structure.Column | |
short | java.sql.SMALLINT | defaults:255, 19, 2 | number |
big_integer | java.sql.NUMERIC | defaults:255, 19, 2 | number |
integer - int | java.sql.INTEGER | defaults:255, 19, 2 | number |
boolean | java.sql.BIT | defaults:255, 19, 2 | number |
big_decimal | java.sql.NUMNERIC | defaults:255, 19, 2 | number |
I put some of liquibase code:
-
org.hibernate.mapping.Column hibernateColumn = (org.hibernate.mapping.Column) columnIterator.next();
Column column = new Column();
column.setName(hibernateColumn.getName());
column.setDataType(hibernateColumn.getSqlTypeCode(mapping)); -->> column 2
if (column.isNumeric())
column.setColumnSize(hibernateColumn.getPrecision()); -->> column 3
else
column.setColumnSize(hibernateColumn.getLength()); -->> column 3
…
column.setTypeName(hibernateColumn.getSqlType(dialect, mapping).replaceFirst("\(.*\)", “”)); -->> column 4
It is clear that boolean, short, integer, big_integer are not the same but the resultant typeNames, precisions and scales are the same in all cases (defaults values in precision and scale).
When you update the database, you can view the next illogical sql results (to oracle databases):
hibernate -> sql data types
short -> number -> short, integer and boolean do not have parameters
integer -> number
boolean -> number
big_integer -> number(19,2) -> big_integer and big_decimal need precision and scale [19 and 2 are the default values]
big_decimal -> number(19,2)
I propose to use dialect fuction to achieve logical type names instead of hibernateColumn method:
-
column.setTypeName(dialect.getTypeName(hibernateColumn.getSqlTypeCode(mapping),
hibernateColumn.getLength(),hibernateColumn.getPrecision(),hibernateColumn.getScale()));
But the problem arrives when you get the sql data types because big_decimal and big_integer need the two parameters in this way: typeName(precision,scale), obtaining:
big_decimal -> number(19,2)(19,2)
big_integer -> number(19,2)(19,2)
(and similar error in other not numeric types)
This error can be rapidly solved and I can update all to SVN, if someone says that it is a correct solution.