Обновление Spring boot 1.3.0 и нестандартный метод JPA не работают

После обновления до весенней загрузки версии 1.3.0.RELEASE, я вижу следующую ошибку при попытке запуска.

Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'productRepository': Invocation of init
method failed; nested exception is
org.springframework.data.mapping.PropertyReferenceException: No
property true found for type boolean! Traversed path: Product.active.
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1192)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
        ... 64 more Caused by: org.springframework.data.mapping.PropertyReferenceException: No property true found for type boolean! Traversed path: Product.active.
        at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75)
        at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327)

Вот соответствующий фрагмент кода, который вызывает проблему. Никаких изменений не было внесено ни в какое хранилище или модель данных.

public interface ProductRepository extends JpaRepository<Product, Long> {
    List<Product> findByActiveTrue_productInfoActiveTrue();
}

@Entity
@DiscriminatorValue(value = "0")
public class Product extends BaseProduct {

    public boolean isSpecial() {
        return special;
    }

    public void setSpecial(boolean special) {
        this.special = special;
    }
}

@Entity(name = "products")
@DiscriminatorColumn(name = "matchtype", discriminatorType = DiscriminatorType.INTEGER)
public abstract class BaseProduct implements Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name = "isspecial")
    protected boolean special;

    @Id
    @GeneratedValue
    @Column(name = "productid")
    private Long productId;

    @Column(name = "active")
    private boolean active;

    @OneToMany(mappedBy = "productId", fetch = FetchType.EAGER)
    private Set<ProductInfo> productInfo;

    @Entity(name = "products_ranges")
    public static class ProductInfo {

        @Id
        @Column(name = "prodrangeid")
        private Long id;

        @Column(name = "product_id")
        private Long productId;

        @Column(name = "active")
        private boolean active;
    }

Любая помощь по этому вопросу будет принята с благодарностью. Я попытался вернуться к более старой версии spring-data-common, но это не работает с новой spring-data-jpa.

Спасибо!

1 ответ

Решение

Если это когда-либо работало, это было ошибкой. findByActiveTrue_productInfoActiveTrue(…) не является допустимым методом запроса. В зависимости от типа вашего домена метод состоит из двух предикатов: active = true а также productInfo.active = true, Те к предикатам должны быть объединены с использованием ключевого слова, которое, я полагаю, в вашем случае будет And, findByActiveTrueAndProductInfoActiveTrue(…) не только лучше читает, но и должно работать.

Чтобы убедиться, что вы понимаете сообщение об ошибке, вот что происходит:

  1. Снимаем префикс до первого By -> ActiveTrue_productInfoActiveTrue
  2. Мы разделили ключевое слово -> ActiveTrue_productInfoActive
  3. Теперь мы пытаемся найти свойства в доменном объекте, начиная с полного соответствия, сокращая его справа.
  4. В итоге мы находим очень левый Active с оставшимся хвостом True_productInfoActive,
  5. Мы повторяем процесс, начиная с 3 с разрешенным типом свойства (Boolean) и в конечном итоге не может найти что-то, true будучи последним сегментом, попробованным.

Вообще говоря, мне было бы интересно услышать, что заставило вас использовать подчеркивания, во-первых, потому что подчеркивание - это, по сути, команда "переместить вложенное свойство вправо" в синтаксический анализатор, что явно не может быть целью вашего метода.

Другие вопросы по тегам