找不到类型为Entry的属性findAllEntries

时间:2017-03-30 16:26:55

标签: java spring

我不知道Spring为什么不喜欢我的代码:

我有Entry.java

@Entity
@Table(name = "entries")
public class Entry {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "text")
    private String text;
}

EntryDao.java

public interface EntryDao extends JpaRepository<Entry, Long> {
    List<Entry> findAllEntries();
}

EntryService.java

@Service
public interface EntryService {

    List<Entry> findAllEntries();

}

EntryServiceImpl.java

public class EntryServiceImpl implements EntryService {
    private EntryDao entryDao;
    private SessionFactory sessionFactory;

    @Override
    @SuppressWarnings("unchecked")
    public List<Entry> findAllEntries()  {
        Session session = this.sessionFactory.getCurrentSession();
        List<Entry> entries = session.createQuery("from entries").list();
        return entries;
    }
}

此代码给出了一个错误:

  

org.springframework.beans.factory.BeanCreationException:创建名称为&#39; entryDao&#39;的init时出错:init方法的调用失败;嵌套异常是org.springframework.data.mapping.PropertyReferenceException:找不到类型为Entry的属性findAllEntries!

我不明白如何处理此错误以及发生此错误的原因。

2 个答案:

答案 0 :(得分:3)

您遇到异常的根本原因是您违反了在Spring Data JPA中声明/创建查询的约定/规则。

The official docs of Spring Data JPA提到:

  

Spring Data存储库抽象的目标是显着减少为各种持久性存储实现数据访问层所需的样板代码量。

抽象的中心接口是Repository,要管理您的实体,您需要声明自己的Repository接口,JPA将帮助您为这些接口创建代理实例。已经有一些基础Repositories,例如CrudRepositoryPagingAndSortingRepository来提供基本功能,因为您可以从他们的名字中看出来,因此通过扩展这些基本功能,您将拥有许多基本方法。要定义更具体的访问方法,您需要按照JPA提供的方式创建查询:

  • 按照方法名称约定
  • 在界面中定义方法
  • 使用@Query注释手动定义

对于第一种方法,the docs of Query Create有详细的说明,这里有一些关键的想法:

  

该机制剥离前缀find ... By,read ... By,query ... By,count ... By,and get ...来自该方法并开始解析其余部分。 introduction子句可以包含其他表达式,例如Distinct,用于在要创建的查询上设置不同的标志。但是,第一个By用作分隔符以指示实际条件的开始。在最基本的层面上,您可以定义实体属性的条件,并将它们与And和Or连接起来

简单来说,JPA将解析方法名称并尝试查找相关属性以为您创建查询条件。

现在让我们来看看您的代码,如果您只想检索所有实体,则不需要定义自己的方法,如果您愿意,已预先定义了findAll个方法根据{{​​1}}内容检索实体,它应该看起来像:

text

但您的方法Entity findByText(String text) 只是不匹配任何规则,因此JPA会向您抛出此类错误消息。

答案 1 :(得分:2)

正如@AbdullahWasi所说,只需使用SpringData中现有的findAll()方法代码即可。您可能希望在代码中放置@Transactional注释,但这取决于您的事务边界。

只需从Dao中删除自定义方法。

public interface EntryDao extends JpaRepository<Entry, Long> {
}

并使用默认弹簧数据findAll

@Transactional
public class EntryServiceImpl implements EntryService {
    private EntryDao entryDao;
    private SessionFactory sessionFactory;

    @Override
    @SuppressWarnings("unchecked")
    public List<Entry> findAllEntries()  {
        return entryDao.findAll();
    }
}