2015-04-23 72 views
4

我有麻烦SPEL和Spring数据JPA工作春数据JPA的SpeI - @Query问题

以下是我的仓库

package eg.repository; 
public interface MyEntityRepository extends JpaRepository<MyEntity, Long>,JpaSpecificationExecutor<MyEntity> { 

    @Query("SELECT e FROM eg.domain.MyEntity e " + 
      "WHERE e.title = :#{#filter.title}" 
    ) 
    Page<MyEntity> list1(@Param("filter") MyFilter filter,Pageable pageable); 
} 

滤波器组件

package eg.service; 

import org.springframework.stereotype.Component; 

@Component("filter") 
public class MyFilter { 

    public String titleFilter() { 
     return "%title%"; 
    } 
    private String title = "title title1"; 
    public Long[] idFilter() { 
     return new Long[] { 
       1L, 2L 
     }; 
    } 
} 

以下是MyEntity

package eg.domain; 
@Entity 
public class MyEntity implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    @Column(name = "title") 
    private String title; 
    ...... 
} 

主类

LOG.info("Application initialized " + annotationConfigApplicationContext); 
     MyEntityRepository myEntityRepository = 
        (MyEntityRepository) annotationConfigApplicationContext.getBean(MyEntityRepository.class); 
     MyFilter filter = annotationConfigApplicationContext.getBean(MyFilter.class); 
     PageRequest pageRequest = new PageRequest(0, 5); 
     Page<MyEntity> page = myEntityRepository.list1(filter,pageRequest); 
     List<MyEntity> entities= page.getContent(); 
     for(MyEntity entity: entities){ 
      System.out.println(entity.getId() + " TITLE " + entity.getTitle()); 
     } 

下面是我得到过滤器的

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myEntityRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Using named parameters for method public abstract org.springframework.data.domain.Page eg.repository.MyEntityRepository.list1(eg.service.MyFilter,org.springframework.data.domain.Pageable) but parameter 'filter' not found in annotated query 'SELECT e FROM eg.domain.MyEntity e WHERE e.title = :#{#filter.title}'! 
+0

为什么你不只是给标题作为参数,而不是像'@Query(“SELECT e FROM eg.domain.MyEntity e WHERE e.title =:filter”)'? –

+0

我只是想让Spel和Spring数据一起工作。一旦这个工程正在计划添加更复杂的东西,如在方法idFilter()等中可以看到的。 – ArunM

+0

我也无法得到一个简单的#{#variable}表达式。 – RedDeckWins

回答

0
private String title = "title title1"; 

标题是私人的错误,我看不出这方面的任何吸气剂属性。可能是这个问题。

+0

Nopes ..我厌倦了吸气剂,也没有运气 – ArunM

+0

你有没有尝试其他的替代品,如'?#{filter.title}' –

0

通过SpEL访问传递的参数对象的值一般工作就像一个魅力,甚至你的语法似乎是正确的。

也许有再次进行比较:Spring Data JPA and SpEL

你真的肯定错误消息都只属于你贴的代码?你以后调整了吗?我简化了一下,这是一个正在运行的测试案例。

实体:

import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 

@Entity 
public class MyEntity { 

    @Id 
    @GeneratedValue 
    private Long id; 

    private String title; 

    public MyEntity(String title) { 
     this.title = title; 
    } 

    public Long getId() { 
     return id; 
    } 

    public String getTitle() { 
     return title; 
    } 

} 

资源库:

package com.example.repository; 

import org.springframework.data.domain.Page; 
import org.springframework.data.domain.Pageable; 
import org.springframework.data.jpa.repository.JpaRepository; 
import org.springframework.data.jpa.repository.Query; 
import org.springframework.data.repository.query.Param; 

import com.example.model.MyEntity; 
import com.example.model.MyFilter; 

public interface MyEntityRepository extends JpaRepository<MyEntity, Long> { 

    @Query("SELECT e FROM MyEntity e WHERE e.title = :#{#filter.title}") 
    Page<MyEntity> list1(@Param("filter") MyFilter filter, Pageable pageable); 

} 

的 “过滤器”:

package com.example.model; 

public class MyFilter { 

    private String title; 

    public MyFilter(String title) { 
     this.title = title; 
    } 

    public String getTitle() { 
     return title; 
    } 

} 

和相关测试:

package com.example.repository; 

import static org.hamcrest.CoreMatchers.is; 
import static org.hamcrest.MatcherAssert.assertThat; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.test.context.SpringBootTest; 
import org.springframework.data.domain.PageRequest; 
import org.springframework.test.context.junit4.SpringRunner; 
import org.springframework.transaction.annotation.Transactional; 

import com.example.model.MyEntity; 
import com.example.model.MyFilter; 

@RunWith(SpringRunner.class) 
@Transactional 
@SpringBootTest 
public class MyEntityRepositoryTests { 

    @Autowired 
    private MyEntityRepository myEntityRepository; 

    @Test 
    public void insertAndReceiveEntityBySpEL() { 
     final String titleA = "A"; 
     final String titleB = "B"; 

     final MyEntity entityA = new MyEntity(titleA); 
     final MyEntity entityB = new MyEntity(titleB); 
     final MyEntity entityB2 = new MyEntity(titleB); 

     myEntityRepository.save(entityA); 
     myEntityRepository.save(entityB); 
     myEntityRepository.save(entityB2); 

     final MyFilter filterA = new MyFilter(titleA); 
     final MyFilter filterB = new MyFilter(titleB); 

     assertThat("Expected one hit for value A!", myEntityRepository.list1(filterA, new PageRequest(0, 5)).getContent().size(), is(1)); 
     assertThat("Expected two hits for value B!", myEntityRepository.list1(filterB, new PageRequest(0, 5)).getContent().size(), is(2)); 
    } 

} 

也许你可以简化你的代码,找出那里到底发生了什么。 SpEL表达式不应该是真正的问题。

一些其他的东西也不可能是你错误的原因但尽管如此它似乎很奇怪:

  • 什么方法titleFilter()idFilter()呢?你在这里没有使用它,它不会被查询使用。

  • 如何在运行时设置/调整MyFilter对象的成员title的值?它只是硬编码吗?因此,没有getter,JPA应该如何访问和使用它进行比较?

  • 为什么您的存储库扩展为JpaSpecificationExecutor

最后一件事是最容易混淆的。是否有可能想与合作?然后你需要一些Predicate检查来实现你的“过滤器”。