Boolean型を外部ドメインクラスに指定したときの挙動について #933
-
目的:DB上で数値型として扱われている項目を、Java上ではBoolean型で扱いたい。相談内容いつもお世話になっております。
このとき、プロジェクトのコンパイル自体は問題なく通ります。 このような処理を内部ドメインクラスで実行すると、特に型変換等指定しなくてもスムーズに動いてくれているようです。 動作環境
経緯現在使用しているDBはPostgresですが、Oracleでの運用も考慮し、DBにboolean型の項目を持つのは極力避けたいと考えております。 このエラーが、プロジェクト側の設定・実装が問題なのか、なにかしら不具合によるものなのか、それとも仕様なのか判断がつかなかったため、ご相談させていただきました。 資産(簡略化しています)tablecreate table xxx_table (
key integer not null
, value varchar(10)
, bool_int smallint
, primary key (key)
);
Entity@Entity
@Getter
public class XxxTable {
@Id
private Integer key;
private String value;
private Boolean boolInt; // External domain class
} Dao@Dao
public interface XxxTableDao {
default List<XxxTable> method(Boolean bool) {
XxxTable_ e = new XxxTable_();
Entityql entityql = new Entityql(Config.get(this));
return entityql
.from(e)
.where(c -> c.eq(e.boolInt, bool)) // org.postgresql.util.PSQLException
.fetch();
}
} Converter@ExternalDomain
public class BoolIntConverter implements DomainConverter<Boolean, Integer> {
@Override
public Integer fromDomainToValue(Boolean value) {
// Boolean を Integer に変換して返す
}
@Override
public Boolean fromValueToDomain(Integer value) {
// Integer を Boolean に変換して返す
}
} Provider@DomainConverters({
BoolIntConverter.class
})
public class DomainConvertersProvider {
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
詳細な共有ありがとうございます。
はい、こちらに相当します。次のバージョンでは基本クラスを外部ドメインクラスとして扱おうとした場合にはエラーを出そうと思います。 「1」や「0」を真偽値として扱うには、基本データ型のマッピングをカスタマイズする方法を推奨します。以下ではその方法を示します。 まず、 import org.seasar.doma.jdbc.JdbcMappingFunction;
import org.seasar.doma.jdbc.JdbcMappingHint;
import org.seasar.doma.jdbc.dialect.PostgresDialect;
import org.seasar.doma.jdbc.type.JdbcTypes;
import org.seasar.doma.wrapper.BooleanWrapper;
import java.sql.SQLException;
public class MyPostgresJdbcMappingVisitor extends PostgresDialect.PostgresJdbcMappingVisitor {
@Override
public Void visitBooleanWrapper(BooleanWrapper wrapper, JdbcMappingFunction p, JdbcMappingHint q) throws SQLException {
return p.apply(wrapper, JdbcTypes.INTEGER_ADAPTIVE_BOOLEAN);
}
} 次に、 import org.seasar.doma.jdbc.SqlLogFormattingFunction;
import org.seasar.doma.jdbc.dialect.PostgresDialect;
import org.seasar.doma.jdbc.type.JdbcTypes;
import org.seasar.doma.wrapper.BooleanWrapper;
public class MyPostgresSqlLogFormattingVisitor extends PostgresDialect.PostgresSqlLogFormattingVisitor {
@Override
public String visitBooleanWrapper(BooleanWrapper wrapper, SqlLogFormattingFunction p, Void q) throws RuntimeException {
return p.apply(wrapper, JdbcTypes.INTEGER_ADAPTIVE_BOOLEAN);
}
} doma-spring-bootを使っている想定で記載しますが、上記の2つのクラスを使って生成した import org.seasar.doma.boot.autoconfigure.DomaConfigBuilder;
import org.seasar.doma.boot.autoconfigure.DomaProperties;
import org.seasar.doma.jdbc.dialect.Dialect;
import org.seasar.doma.jdbc.dialect.PostgresDialect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DomaConfiguration {
@Bean
public PostgresDialect dialect() {
PostgresDialect dialect = new PostgresDialect(
new MyPostgresJdbcMappingVisitor(),
new MyPostgresSqlLogFormattingVisitor());
return dialect;
}
@Bean
public DomaConfigBuilder domaConfigBuilder(DomaProperties domaProperties, Dialect dialect) {
DomaConfigBuilder builder = new DomaConfigBuilder(domaProperties);
builder.dialect(dialect);
return builder;
}
} 上記の設定により、DB上の数値型をJava上の |
Beta Was this translation helpful? Give feedback.
詳細な共有ありがとうございます。
はい、こちらに相当します。次のバージョンでは基本クラスを外部ドメインクラスとして扱おうとした場合にはエラーを出そうと思います。
「1」や「0」を真偽値として扱うには、基本データ型のマッピングをカスタマイズする方法を推奨します。以下ではその方法を示します。
まず、
PostgresDialect.PostgresJdbcMappingVisitor
を継承し、JDBCのマッピングにおいてBoolean型をInteger型で扱えるようにします。