来自 JpaRepository 接口的查询

Posted

技术标签:

【中文标题】来自 JpaRepository 接口的查询【英文标题】:Queries from JpaRepository interface 【发布时间】:2017-06-09 20:00:12 【问题描述】:

这个问题与 Spring MVC 项目有关,我确实在其中使用 Hibernate 和 JPA。 因为消息是一个实体类

import java.io.Serializable;
import java.time.LocalDate;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "StoredMessage")
public class StoredMessage implements Serializable

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long messageId;
    @Column(nullable = false)
    private Long userId;
    @Column(nullable = false)
    private String message;
    @Column(nullable = false)
    private LocalDate date;
    @ManyToOne
    private User user;

    public StoredMessage() 
       super();
    

   public StoredMessage(Long messageId, Long userId, String message, LocalDate date) 
      super();
      this.messageId = messageId;
      this.userId = userId;
      this.message = message;
      this.date = date;
  

  public Long getMessageId() 
      return messageId;
  

  public void setId(Long messageId) 
      this.messageId = messageId;
  

  public Long getUserId() 
      return userId;
  

  public void setUserId(Long userId) 
      this.userId = userId;
  

  public String getMessage() 
      return message;
  

  public void setMessage(String message) 
      this.message = message;
  

  public LocalDate getDate() 
      return date;
  

  public void setDate(LocalDate date) 
      this.date = date;
  


为了执行一些简单的查询,使用了从 JpaRepository 派生的接口。

import org.springframework.data.jpa.repository.JpaRepository;

import free.oauth.model.StoredMessage;

public interface MessageRepository extends JpaRepository<StoredMessage,  Long> 

    public void saveStoredMessage(StoredMessage message);

    public void delete(Long MessageId);

    public boolean findByMessageId(Long mesageId);

    public StoredMessage findStoredMessageByMessageId(Long mesageId);

    public boolean update(StoredMessage mesage);

通过运行项目,它会得到类似的错误

Caused by: org.springframework.data.mapping.PropertyReferenceException: No property saveStoredMessage found for type StoredMessage!
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:77)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:329)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:309)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:272)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:243)
at org.springframework.data.repository.query.parser.Part.<init>(Part.java:76)
at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:235)
at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:373)
at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:353)
at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:84)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:63)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:103)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:214)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:77)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:435)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:220)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:266)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:252)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
... 56 more

这个接口有什么问题,在这种类型的接口中必须遵守规则?

【问题讨论】:

【参考方案1】:

关于保存和删除,它们是开箱即用的,并且已经存在于界面中:

void delete(T entity)
<S extends T> S save(S entity)

两者都在 JpaRepository 扩展的 CrudRepository 接口上定义。

关于更新,从数据库中获取查询并放入持久化上下文之后对查询的任何更新都将在事务完成后刷新到数据库中。

如果您想明确更新,请尝试以下帖子: How do I update an entity using spring-data-jpa?

更新

而不是这个:

public StoredMessage findStoredMessageByMessageId(Long mesageId);

你会使用

StoredMessage findOne(long messageId)

也来自 CrudRepository 接口

最后,如果你想不是通过 id 而是通过某个字段来搜索唯一实体,那么可以这样使用:

StoredMessage findOneStoredMessageByMessage(String message);

【讨论】:

以上是关于来自 JpaRepository 接口的查询的主要内容,如果未能解决你的问题,请参考以下文章

Spring Data JPA 实例查询

Spring Data JPA实现简单条件查询

Spring JPA no @Transnational 保存 JpaRepository

spring jpa 带参数分页查询

Spring Boot + JPA 多模块项目无法注入 JpaRepository 接口

Spring Data JPA 简单查询-接口方法