2012-04-11 8 views
4

Derbyデータベースのクエリに問題があります。私はJPAでHibernateを使用しています。問題は(おそらく)ブール値の列に関連しています。各クエリはエラーで終了します:Hibernate + Derby: 'BOOLEAN'と 'INTEGER'の比較はサポートされていません

org.hibernate.exception.SQLGrammarException: 'BOOLEAN'と 'INTEGER'の比較はサポートされていません。タイプは同等でなければなりません。文字列型も照合順序が一致している必要があります。照合が一致しない場合は、オペランドをキャストしてデフォルトの照合順序にすることが考えられます(例:SELECT tablename FROM sys.systables WHERE CAST(tablename AS VARCHAR(128))= 'T1')

サンプルコードと設定を見つけることができます。サンプルは読みやすくするために簡素化されています。ここに私のJPAエンティティは次のとおりです。

@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 + " ]"; 
    } 
} 

マイJPAクエリ:

SELECT t FROM Task t WHERE deleted = false 

マイJPA構成:

<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> 

何が悪いのでしょうか?それを修正するには?ご意見ありがとうございます。

+0

ダービーでTask.deletedのデータ型は何ですか?それは長いショットですが、多分hibernate.hbm2ddl.auto = updateはデータ型の変更を適用していません。 – samlewis

+0

Task.deletedはDerbyデータベースのブール値です。データベーススキーマは、エンティティクラスと最新の同期をとっています。 – 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"); 
    } 
} 

私はダービーデータ型への方言で「真」と「偽」の定数のマッピングを設定した方が良いですが、上記の今には十分だと思います。あなたは、パラメータとして、あなたのブール値を設定する必要が

4

Booleanデータ型がDerby 10.7で追加された場合は、10.7以降を使用しているように見えるので、Booleanサポートを追加するorg.hibernate.dialect.DerbyTenSevenDialect方言を使用する必要があります。

+0

残念ながら、これは役に立たなかった。どちらの方言に対しても、ログに警告があります: "DerbyDialect方言は廃止されましたが、代わりにバージョン固有の方言の1つを使用してください"。同様の問題は既にHibernateチームにバグとして報告されています:[bug1](https://hibernate.onjira.com/browse/HHH-6961?page=com.atlassian.jirafisheyeplugin%3Afisheye-issuepanel)と[bug2](https ://hibernate.onjira。com/browse/HHH-7059)助けてくれてありがとう - 私はダービーをダウングレードしようとしています。 – Rafal

+0

ところで、私のDerbyバージョンは10.8.1.2です – Rafal

3

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

が、それはあなたのために働くことを願っています。)

ラファウのアプローチを使用し
2

だけでなく、私の中

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

を追加する必要があります方言。それ以外の場合は、Hibernate 4.2.8では動作しません。

私のアプリケーションがOracleとDerbyに対して実行されるため、私はpersistence.xmlで明示的に私の方言を指定することができませんでした。だから、私は方言のための方言のリゾルバを追加しました:

<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; 
    } 
} 
関連する問題