首页 > 解决方案 > 带有 @query 的 Spring 规范

问题描述

我有一个名为“内容”的表,其中有一个名为“created_at”的字段。我正在尝试在此表中使用可分页和规范。

规格完美无缺,但我对可分页有问题。如果我使用从存储库继承的方法来搜索可分页,则无法识别带有下划线的字段并尝试拆分他。给出这个错误:

"No property created found for type Content!"

如果我在存储库可分页中创建一个方法,但规范没有。这是我的存储库:

@Repository
public interface ContentRepository extends JpaRepository<Content, 
String>,JpaSpecificationExecutor<Content> {

   @Query(value = "SELECT * FROM content", nativeQuery = true)
   public Page<Content> findAll(Specification<Content> specification, Pageable pageable);    

}

我怎么能两者都做?

内容类:

 @Entity
 @Table(name = "content")
 @Setter
 @Getter
 public class Content {

  @Id
  @Column(name = "id")
  private String id;

  @Column
  private String name;

  @Column
  private String description;

  @Column(columnDefinition = "TEXT")
  private String content;

  @Column(columnDefinition = "TEXT")
  private String reference;

  @ManyToOne
  @JoinColumn(nullable = false)
  private User author;

  @ManyToOne
  @JoinColumn(nullable = true)
  private Agenda agenda;

  @ManyToOne
  @JoinColumn(nullable = false)
  private ContentType contenttype;

  @Column(columnDefinition = "boolean default true")
  private boolean enabled;

  @Column(columnDefinition = "boolean default false")
  private boolean approved;

  @Column
  private Date sent_at;
  @Column
  private Date created_at;
  @Column
  private Date updated_at;
  @Column
  private Date deleted_at;

}

标签: javaspringspring-bootspring-data-jpaspring-data

解决方案


如果您可以控制属性命名,请避免在实体属性名称中使用下划线。这将解决您的存储库问题,并产生更清晰的代码库。开发人员在您处理代码后会感谢您。

请注意,这不仅仅是我的观点:Spring 特别不鼓励使用下划线

由于我们将下划线视为保留字符,因此我们强烈建议遵循标准的 Java 命名约定(即不在属性名称中使用下划线,而是使用驼峰式命名)。

这个 JIRA 问题显示了为什么使用此建议更新了文档,并删除了描述双下划线选项的部分。

我怀疑您的根本问题是 Spring/Hibernate 没有将骆驼案例属性名称映射到您为数据库中的列所拥有的蛇案例名称。您真正需要的是让您的属性名称在 hierate 生成为 created_at 的 SQL 中解释。

这就是为什么您的属性名称中的下划线是“必需的”?如果是这样,有几个解决方案:

选项 1:@Column 注释

要让 JPA/Hibernate 映射到正确的列名,您可以明确地告诉它名称。使用注释@Column(name="...")告诉它在 SQL 中使用哪些列名。然后字段名称不受列名称的约束。

@Entity
@Table(name = "content")
@Setter
@Getter
public class Content {
     @Id
     @Column(name="created_at")
     private String createdAt;
}

选项 2:改进的命名策略
或者,如果您的应用程序有大量实体,而不是添加@Column到每个属性,将配置文件中的默认命名策略更改为hibernate 改进的命名策略

<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>

此命名策略会将 camelCase 转换为 SNAKE_CASE。然后你的类看起来就像这样简单:

@Entity
public class Content{
     @Id
     private String createdAt;

}

使用其中任何一个选项,当它创建 SQL 时,它会将列名解析为:

 created_at

注意:如果您正在使用或可以使用 Spring Boot,自动配置默认将使用SpringNamingStrategy,这是 hibernate 改进策略的略微修改版本。您无需执行任何操作即可获得这种改进的命名策略。

终点线:

在您的属性名称中使用驼峰式大小写,您可以使用驼峰式大小写编写存储库方法名称,并且您可以停止尝试使用双下划线:

@Repository
@Transactional
public interface ContentRepository extends CrudRepository<Content, String> {  
      @Query(value = "SELECT * FROM content", nativeQuery = true)
       List<Student> findAll(Specification<Content> specification, Pageable pageable);   
}

推荐阅读