有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

带有@query的JavaSpring规范

我有一个名为“content”的表,其中有一个名为“created_at”的字段。 我试图在这个表中使用pageable和规范

规范工作完美,但我有一个问题,可分页。如果我使用从存储库继承的方法来搜索页面,请不要识别带下划线的字段,并尝试拆分该字段。给文这个错误:

"No property created found for type Content!"

如果我在存储库中创建了一个方法,那么pageable可以工作,但是规范不能。 这是我的存储库:

@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;

}

共 (1) 个答案

  1. # 1 楼答案

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

    注意,这不仅仅是我的观点:Spring specifically discourages using underscores

    As we treat underscore as a reserved character we strongly advise to follow standard Java naming conventions (i.e. not using underscores in property names but camel case instead).

    this JIRA issue显示了为什么使用此reccomendation更新文档,并且删除了描述双下划线选项的部分

    我怀疑您的根本问题是Spring/Hibernate没有将camel-case属性名称映射到数据库中列的snake-case名称。您真正需要的是在HIBRATE在创建时生成的SQL中解释您的属性名

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

    选项1:@列注释

    要让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 improved naming strategy

    <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
    

    注意:如果您正在使用或可以使用SpringBoot,自动配置默认值将使用SpringNamingStrategy,这是hibernate改进策略的一个稍加修改的版本。您不必做任何事情就可以获得这种改进的命名策略

    终点线:

    在属性名称中使用camel-case,您可以使用camel-case编写存储库方法名称,并且您可以停止尝试使用双下划线:

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