Reputation: 1396
I am starting my spring
container in validate
mode
autoddl=validate
I am getting a validation exception like this
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-
validation: wrong column type encountered in column [amount] in table [Balance];
found [numeric (Types#NUMERIC)], but expecting [int8 (Types#BIGINT)]
and my DDL script goes like this
CREATE TABLE Balance(stratr VARCHAR(25), histFromDate TIMESTAMP WITHOUT TIME
ZONE,amount numeric(11, 0))
and my attribute in JPA entity goes like this
@Column(name="amount", precision=11, scale=0) //have specified precision and scale
private Long amount ;
where I have used import javax.persistence.Column
.Since I have annotated the exact precision and scale, Shouldn't hibernate validate with these info that I have provided through the column annotation? What could have I missed ?
I cannot do the following
@Column(
columnDefinition = "NUMERIC(11,0)"
)
private Long amount;
because I don't know the data store of this JPA entity.
I also tried generating the script by the following property
<prop key="javax.persistence.schema-generation.scripts.action">drop-and-create</prop>
<prop key="javax.persistence.schema-generation.scripts.create-target">./l/create.sql</prop>
<prop key="javax.persistence.schema-generation.scripts.drop-target">./l/drop.sql</prop>
This is also generating as int8
and not numeric(11,0)
. What can be done to solve this ?
Upvotes: 5
Views: 9721
Reputation: 10716
It's really quite difficult to grasp what you're trying to accomplish, but if I understood correctly:
NUMERIC(11,0)
, which would make it Postgres-specificNUMERIC(11,0)
for Postgres and not INT8
that Hibernate would normally use for a Long
in Postgres (and is hoping to find in your schema upon validation)In short, you want a per-database customization that is not reflected in your entity mapping. The only way to accomplish that is to customize the dialect that Hibernate is using for your version of Postgres. What you need to do is:
determine which dialect version is being selected for your Postgres database (it will be one of the following: PostgresPlusDialect
, PostgreSQL81Dialect
, PostgreSQL82Dialect
, PostgreSQL91Dialect
, PostgreSQL92Dialect
,PostgreSQL93Dialect
, PostgreSQL94Dialect
, PostgreSQL95Dialect
, PostgreSQL9Dialect
)
extend from that class, adding the following definition:
public MyCustomPostgresDialect() {
super();
registerColumnType(Types.BIGINT, "NUMERIC(11, 0)");
}
(If you want to be able to control the precision and scale using @Column(precision = ..., scale = ...
), use registerColumnType(Types.BIGINT, "NUMERIC($p, $s)")
instead)
hibernate.dialect
property to persistence.xml
, pointing to the fully qualified class name of your custom dialectNote that this will, of course, affect all Long
properties in your data model, not just the specific field in question.
Upvotes: 3
Reputation: 1306
I can think on only reason is because in your entity amount type is Long
but in JPA creation script your DDL specified as amount numeric(11, 0)
here second param suggest decimal precision.
As you can see java tries to enter data in Long
type (ie. 10.0000), similar to BigInt in Database but database does not accept such decimal value being type numeric (11,0)
You should be able to resolve it by either changing your java code to have entity amount type int
or change DDL to have scaleInt. ie. NUMERIC(11,5)
.
However best bet would be to have DECIMAL type for any non Integer type.
http://www.h2database.com/html/datatypes.html#decimal_type
Upvotes: 1