Запрос типа Java JPA

#java #spring #jpa

Вопрос:

Я пытаюсь построить запрос, но при вводе идентификаторов я получаю ошибку. Я не понимаю, почему.

Это для Java 8 spring-data-jpa 1.11.23.РЕЛИЗ

 public List<E> findByIds(List<Long> ids) throws Exception {

    try {

        TypedQuery typedQuery = entityManager.createQuery(String.format("SELECT x FROM %s x WHERE x.id IN (?1)",domainClass.getSimpleName()),domainClass.getClass());
        typedQuery.setParameter(1, ids);
        return typedQuery.getResultList();

    } catch (Exception e) {
        logger.error(e.getMessage(),e);
        throw e;
    }
}
 
 @MappedSuperclass
@EntityListeners(value = AbstractEntityListener.class)
public abstract class AbstractEntity implements Serializable, Persistable<Long>
{

    @Id
    @TableGenerator(name = "TABLE_GEN", table = "id_sequence", pkColumnName = "seq_name", valueColumnName = "seq_count", pkColumnValue = "Entity")
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN")
    @Basic(optional = false)
    @Column(name = "id")
    private Long id;
    ...
 

Ошибка

16:02:45,103 ОШИБКА DaoImpl:528 — Вы попытались установить значение типа класса java.util.Список массивов для параметра 1 с ожидаемым типом класса java.lang.Длинный из строки запроса ВЫБЕРИТЕ x ИЗ MyEntity x, ГДЕ x.id В (?1).

java.lang.Исключение IllegalArgumentException: Вы попытались установить значение класса типа java.util.Список массивов для параметра 1 с ожидаемым типом класса java.lang.Длинный из строки запроса ВЫБЕРИТЕ x ИЗ My_Entity x, ГДЕ x.id В (?1).

в орг.затмение.настойчивость.внутренние.СПД.QueryImpl.setParameterInternal(QueryImpl.в Java:946)
в орг.затмение.настойчивость.внутренние.СПД.QueryImpl.setParameterInternal(QueryImpl.в Java:920)
в орг.затмение.настойчивость.внутренние.СПД.EJBQueryImpl.setParameter(EJBQueryImpl.в Java:479)
в орг.затмение.настойчивость.внутренние.СПД.EJBQueryImpl.setParameter(EJBQueryImpl.Ява:1)

Ответ №1:

этот проект использует

    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.7.8</version>
    </dependency>
 

Похоже, они не проверяют наличие оператора «В»

   protected void setParameterInternal(String name, Object value, boolean isIndex) {
    DatabaseQuery query = this.getDatabaseQueryInternal();
    if (query.getQueryMechanism().isJPQLCallQueryMechanism()) {
        int index = query.getArguments().indexOf(name);
        if (index == -1) {
            if (isIndex) {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-argument-index", new Object[]{name, query.getEJBQLString()}));
            }

            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-argument-name", new Object[]{name, query.getEJBQLString()}));
        }

        Class type = (Class)query.getArgumentTypes().get(index);
        if (!this.isValidActualParameter(value, type)) {
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-incorrect-parameter-type", new Object[]{name, value.getClass(), query.getArgumentTypes().get(index), query.getEJBQLString()}));
        }
    } else if (isIndex amp;amp; name.equals("0")) {
        throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-wrong-argument-index", new Object[]{name, query.getSQLString()}));
    }

    this.parameterValues.put(name, value);
}

protected boolean isValidActualParameter(Object value, Class parameterType) {
    return value == null ? true : BasicTypeHelperImpl.getInstance().isAssignableFrom(parameterType, value.getClass());
}
 

Я буду избегать использования метода setParameter.

Комментарии:

1. Берегись! Я не использовал eclipselink (только спящий режим для JPA), но не использую параметризованные запросы, если вы это имеете в виду, это подвергнет вас SQL-инъекции

2. Соглашаться. Мне нужно удалить зависимость от eclipse.