Каковы наилучшие обходные пути для известных проблем с проверкой схемы Hibernate для столбцов с плавающей запятой при использовании Oracle 10g?
У меня есть несколько классов Java с двойными полями, которые я сохраняю через Hibernate. Например, у меня есть
@Entity
public class Node ...
private double value;
Когда Hibernate org.hibernate.dialect.Oracle10gDialect
создает DDL для таблицы Node, он отображает поле значения в тип с двойной точностью.
create table MDB.Node (... value double precision not null, ...
Похоже, что в Oracle "двойная точность" является псевдонимом для "float". Поэтому, когда я пытаюсь проверить схему базы данных с помощью метода org.hibernate.cfg.AnnotationConfiguration.validateSchema()
, Oracle, похоже, описывает столбец значений как "float". Это заставляет Hibernate выкидывать следующее исключение
org.hibernate.HibernateException: Wrong column type in DBO.ACL_RULE for column value. Found: float, expected: double precision
Очень похожая проблема приведена в базе данных Hibernate JIRA как HHH-1961. Я бы хотел избегать делать что-либо, что нарушит поддержку MySql, Postgres и Sql Server, поэтому расширение Oracle10gDialect
представляется наиболее перспективным из обходных решений, упомянутых в HHH-1961. Но расширение диалекта - это то, чего я никогда не делал раньше, и я боюсь, что могут быть какие-то неприятные ошибки. Каков наилучший способ решения этой проблемы, который не нарушит нашу совместимость с MySql, Postgres и Sql Server?
Ответы
Ответ 1
Это известное ограничение механизма проверки схемы, проверьте HHH-2315. Итак, у вас есть три варианта (на самом деле четыре, но я думаю, что деактивация проверки не нужна). Или:
-
Используйте float
вместо double
на уровне Java - возможно, это не вариант.
-
Патч org.hibernate.mapping.Table.validateColumns(Dialect dialect, Mapping mapping, TableMetadata tableInfo)
, чтобы добавить особое условие для этого конкретного случая - это не очень легкий вариант.
-
Расширяет org.hibernate.dialect.Oracle10gDialect
, чтобы использовать float
для типа SQL double
public class MyOracle10gDialect extends Oracle10gDialect {
public MyOracle10gDialect() {
super();
}
protected void registerNumericTypeMappings() {
super.registerNumericTypeMappings();
registerColumnType( Types.DOUBLE, "float" );
}
}
Более поздний вариант кажется безопасным, но потребует некоторого тестирования, чтобы увидеть, не вносит ли он никакой регрессии. Я не смотрел код драйвера JDBC Oracle, поэтому не могу сказать, как float
и double precision
отличаются на уровне драйвера.
Ответ 2
просто добавление (columnDefinition = "NUMBER (9,2)" ) работает!
@Column(name = "CREDIT_AMOUNT", columnDefinition = "NUMBER(9,2)")
@Basic
private double creditAmount;
Ответ 3
Была аналогичная проблема HHH-1598 с отображением HSQL булевых полей и обсуждение ее здесь.
Решение, которое я выбрал использовать, было в обсуждении, упомянутом выше, с расширением HSQLDialect.
Я не видел проблем с этим, хотя я использую только HSQL в тестах.
Это, конечно, не мешает какой-либо другой БД.
Ответ 4
Используйте атрибут 'scale' для вашего участника.