Вопрос по java – Hibernate + Derby: сравнения между «BOOLEAN» и «INTEGER» не поддерживаются

4

У меня проблема с запросом базы данных Derby. Я использую Hibernate с JPA. Проблема связана (вероятно) с логическими столбцами. Каждый запрос заканчивается ошибкой:

org.hibernate.exception.SQLGrammarException: Comparisons between 'BOOLEAN' and 'INTEGER' are not supported. Types must be comparable. String types must also have matching collation. If collation does not match, a possible solution is to cast operands to force them to the default collation (e.g. SELECT tablename FROM sys.systables WHERE CAST(tablename AS VARCHAR(128)) = 'T1')

Ниже вы можете найти пример кода и конфигурации. Образцы упрощены для удобства чтения. Вот моя сущность JPA:

<code>@Entity
public abstract class Task implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    protected long id;

    @Column
    protected boolean deleted;

    public long getId() {
        return id;
    }

    public boolean isDeleted() {
        return deleted;
    }

    public void setId(long id) {
        this.id = id;
    }

    public void setDeleted(boolean deleted) {
        this.deleted = deleted;
    }

    @Override
    public int hashCode() {
        return id;
    }

    @Override
    public boolean equals(Object object) {
        if (object == null) {
            return false;
        }

        if (!this.getClass().equals(object.getClass())) {
            return false;
        }

        EntityObject other = (EntityObject) object;

        if (this.id != other.id) {
            return false;
        }

        return true;
    }

    @Override
    public String toString() {
        return "EntityObject[ id=" + id + " ]";
    }
}
</code>

Мой запрос JPA:

<code>SELECT t FROM Task t WHERE deleted = false
</code>

Моя конфигурация JPA:

<code><persistence-unit name="PU1" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/myapp</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
  <property name="hibernate.hbm2ddl.auto" value="update"/>
  <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
</properties>
</persistence-unit>
</code>

Что случилось? Как это исправить? Спасибо за любые предложения.

Task.deleted является логическим значением в базе данных Derby. Схема базы данных постоянно синхронизируется с классами сущностей. Rafal
Какой тип данных Task.deleted в дерби? Это долгий путь, но, возможно, hibernate.hbm2ddl.auto = update не применяет изменения типа данных. samlewis

Ваш Ответ

4   ответа
2

@Override
public String toBooleanValueString(boolean bool) {
    return bool ? "1" : "0";
}

на моем диалекте. В противном случае он не работает в Hibernate 4.2.8.

Также я не смог явно указать свой диалект в файле persistence.xml, так как мое приложение работает с Oracle и Derby. Поэтому я добавил средство распознавания диалекта для своего диалекта:

<property name="hibernate.dialect_resolvers" value="...DerbyBoolAsIntDialectResolver"/>

Сам решатель:

public class DerbyBoolAsIntDialectResolver extends AbstractDialectResolver {
    @Override
    protected Dialect resolveDialectInternal(DatabaseMetaData metaData) throws SQLException {
        String databaseName = metaData.getDatabaseProductName();
        int databaseMajorVersion = metaData.getDatabaseMajorVersion();

        if ( "Apache Derby".equals( databaseName ) ) {
            final int databaseMinorVersion = metaData.getDatabaseMinorVersion();
            if ( databaseMajorVersion > 10 || ( databaseMajorVersion == 10 && databaseMinorVersion >= 7 ) ) {
                return new DerbyBoolAsIntDialect();
            }
        }
        return null;
    }
}
4

вы, похоже, используете 10.7 или новее, поэтому вам следует использоватьorg.hibernate.dialect.DerbyTenSevenDialect диалект, который добавляет булеву поддержку.

К сожалению, это не помогло. Более того, для обоих диалектов в журналах есть предупреждение: & quot; Диалект DerbyDialect устарел; вместо этого используйте один из специфических для версии диалектов. Подобная проблема уже сообщена команде Hibernate как ошибка:bug1 а такжеbug2 Спасибо за помощь - пока попробую понизить рейтинг Дерби. Rafal
Кстати, моя версия Derby 10.8.1.2 Rafal
0

которое работает для меня:

import java.sql.Types;
import org.hibernate.dialect.DerbyTenSevenDialect;

public class DerbyDialect extends DerbyTenSevenDialect {

    public DerbyDialect() {
        // fix Derby dialect boolean data type mapping error
        registerColumnType(Types.BOOLEAN, "INTEGER");
    }
}

Я полагаю, что лучше настроить «true» и «ложь»; сопоставление констант в диалекте с типом данных Derby, но на данный момент достаточно хорошо.

3

String queryString = "SELECT t FROM Task t WHERE t.deleted = :trueValue";
Query query = entityManager.createQuery(queryString);
query.setParameter("trueValue", true);
query.getResultList();

Надеюсь, это будет работать для вас;)

Похожие вопросы