Невозможно выполнить sql-запрос для индексированного строкового поля.
У меня есть объект в кеше Ignite.У него есть поле String, которое я хочу использовать для запроса SQL.Но выполнение не удалось с исключением.Кажется, Ignite думает, что String - это BLOB, а не VARCHAR, как я ожидал.Я пытался использовать 'LIKE', 'REGEX' и '=' для SELECT, но это также не удалось.Он хорошо работает только с шестнадцатеричными строками.
@Data
@Builder
public class MyEntity {
private String someForeignId;
private Integer status;
private String data;
private Long hash;
//Skipped
}
//Method to retrieve entity id by fields
Optional<Long> getEntityIdBySomeForeignIdAndData(final String someForeignId, final String data) {
final SqlQuery<Long, MyEntity> query =
new SqlQuery<>(
MyEntity.class,
"select * where MyEntity.someForeignId = ? and MyEntity.data = ?");
return StreamEx.of(myEntitCache.query(query.setArgs(someForeignId, data)).iterator())
.mapToEntry(Cache.Entry::getKey, Cache.Entry::getValue)
.findFirst()
.map(Map.Entry::getKey);
}
//beans.bean.property.list section of ignite.xml
<bean class="org.apache.ignite.cache.QueryEntity">
<property name="keyType" value="java.lang.Long"/>
<property name="valueType" value="com.foo.entity.MyEntity"/>
<property name="fields">
<map>
<entry key="someForeignId" value="java.lang.String"/>
<entry key="status" value="java.lang.Integer"/>
<entry key="data" value="java.lang.String "/>
</map>
</property>
<property name="indexes">
<list>
<bean class="org.apache.ignite.cache.QueryIndex">
<constructor-arg value="someForeignId"/>
</bean>
<bean class="org.apache.ignite.cache.QueryIndex">
<constructor-arg value="status"/>
</bean>
<bean class="org.apache.ignite.cache.QueryIndex">
<constructor-arg value="data"/>
</bean>
</list>
</property>
</bean>
Я ожидал найти ключ сущности по точному совпадению полей someForeignId и данных с помощью оператора SQL, но он работает только с соответствием someForeignId, поскольку он шестнадцатеричный.Мне нужно исправить запрос, чтобы соответствовать любые строковые значения тоже.Теперь у меня есть следующее исключение:
SEVERE: Failed to execute local query.
class org.apache.ignite.IgniteCheckedException: Failed to execute SQL query. Hexadecimal string with odd number of characters: "http://foobar.bar"; SQL statement:
SELECT
"MyEntity".__Z0._KEY __C0_0,
"MyEntity".__Z0._VAL __C0_1
FROM "MyEntity".MYENTITY __Z0
WHERE (__Z0.SOMEFOREIGNID = ?1) AND (__Z0.DATA = ?2) [90003-197]
at org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeSqlQuery(IgniteH2Indexing.java:1428)
at org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeSqlQueryWithTimer(IgniteH2Indexing.java:1489)
at org.apache.ignite.internal.processors.query.h2.twostep.GridMapQueryExecutor.onQueryRequest0(GridMapQueryExecutor.java:930)
at org.apache.ignite.internal.processors.query.h2.twostep.GridMapQueryExecutor.onQueryRequest(GridMapQueryExecutor.java:705)
at org.apache.ignite.internal.processors.query.h2.twostep.GridMapQueryExecutor.onMessage(GridMapQueryExecutor.java:240)
at org.apache.ignite.internal.processors.query.h2.twostep.GridMapQueryExecutor$2.onMessage(GridMapQueryExecutor.java:200)
at org.apache.ignite.internal.managers.communication.GridIoManager$ArrayListener.onMessage(GridIoManager.java:2349)
at org.apache.ignite.internal.managers.communication.GridIoManager.invokeListener(GridIoManager.java:1569)
at org.apache.ignite.internal.managers.communication.GridIoManager.processRegularMessage0(GridIoManager.java:1197)
at org.apache.ignite.internal.managers.communication.GridIoManager.access$4200(GridIoManager.java:127)
at org.apache.ignite.internal.managers.communication.GridIoManager$9.run(GridIoManager.java:1093)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.h2.jdbc.JdbcSQLException: Hexadecimal string with odd number of characters: "http://foobar.bar"; SQL statement:
SELECT
"MyEntity".__Z0._KEY __C0_0,
"MyEntity".__Z0._VAL __C0_1
FROM "MyEntity".MYENTITY __Z0
WHERE (__Z0.SOMEFOREIGNID = ?1) AND (__Z0.DATA = ?2) [90003-197]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.util.StringUtils.convertHexToBytes(StringUtils.java:913)
at org.h2.value.Value.convertTo(Value.java:1078)
at org.h2.value.Value.convertTo(Value.java:617)
at org.h2.value.Value.convertTo(Value.java:592)
at org.h2.expression.Comparison.getValue(Comparison.java:272)
at org.h2.expression.ConditionAndOr.getValue(ConditionAndOr.java:93)
at org.h2.expression.Expression.getBooleanValue(Expression.java:178)
at org.h2.command.dml.Select.isConditionMet(Select.java:312)
at org.h2.command.dml.Select$LazyResultQueryFlat.fetchNextRow(Select.java:1455)
at org.h2.result.LazyResult.hasNext(LazyResult.java:79)
at org.h2.result.LazyResult.next(LazyResult.java:59)
at org.h2.command.dml.Select.queryFlat(Select.java:527)
at org.h2.command.dml.Select.queryWithoutCache(Select.java:633)
at org.h2.command.dml.Query.queryWithoutCacheLazyCheck(Query.java:114)
at org.h2.command.dml.Query.query(Query.java:352)
at org.h2.command.dml.Query.query(Query.java:333)
at org.h2.command.CommandContainer.query(CommandContainer.java:114)
at org.h2.command.Command.executeQuery(Command.java:202)
at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:114)
at org.apache.ignite.internal.processors.query.h2.PreparedStatementExImpl.executeQuery(PreparedStatementExImpl.java:67)
at org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeSqlQuery(IgniteH2Indexing.java:1421)
... 13 more