简体   繁体   English

Spring JPA Hibernate 在可分页请求中使用旧的 @Column 名称:PropertyReferenceException

[英]Spring JPA Hibernate uses old @Column names in Pageable requests: PropertyReferenceException

I've encountered a problem where Spring doesn't see new @Column names of @Entity我遇到了一个问题,即 Spring 看不到 @Entity 的新 @Column 名称

Exact example which I run:我运行的确切示例:

package pckg;

import javax.persistence.*;

@Entity 
@Table(name = "example")
class Example {
    
    @Column(name = "id")
    public int id;
    
    @Column(name = "old")
    public int old;
}
package repo;

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

public interface ExampleRepository extends JpaRepository<Example, Int> {
    Example findById(long id);
}

Rest code is Scala, which, I hope, is fine enough to read其余代码是 Scala,我希望它足以阅读

package controller;

import repo.ExampleRepository
import pckg.Example

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.domain.{Page, PageRequest, Sort}
import org.springframework.web.bind.annotation.{GetMapping, RequestParam, RestController}

class ExampleController {

  @Autowired
  private var repo: ExampleRepository = _

  @GetMapping(value = Array("/example"))
  def getPage(@RequestParam(value = "page",   defaultValue = "0")  page:   String,
              @RequestParam(value = "size",   defaultValue = "10") size:   String,
              @RequestParam(value = "sort",   defaultValue = "id") sortBy: String) Array[Example] = try {
    val pageNumber = page.toInt
    val requestedSize = size.toInt
    val sort = Sort.by(sortBy)
    
    val pageable = PageRequest.of(pageNumber, requestedSize, sort)
    val resultPage: Page[Example] = repo.findAll(pageable)

    resultPage.getContent.asScala.toArray
  } catch {
    case e: Throwable => Array.empty
  }
}
import org.springframework.boot.{CommandLineRunner, SpringApplication}
import org.springframework.boot.autoconfigure.SpringBootApplication

@SpringBootApplication
class App {}

object App {
  def main(args: Array[String]): Unit = {
    SpringApplication.run(classOf[App], args: _*)
  }
}

application.properties应用程序属性

spring.datasource.url=jdbc:postgresql://localhost:5432/example
spring.datasource.username=example
spring.datasource.password=example
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create

I build and run this code, testing with browser, making requests on localhost:8080/example endpoint with parameter sort="old" like this: localhost:8080/example?sort=old我构建并运行此代码,使用浏览器进行测试,在 localhost:8080/example 端点上使用参数 sort="old" 发出请求,如下所示:localhost:8080/example?sort=old

And then I change @Column name from "old" to "bnew" like this:然后我将@Column 名称从“old”更改为“bnew”,如下所示:

package pckg;

import javax.persistence.*;

@Entity 
@Table(name = "example)
class Example {

    @Column(name = "id")
    public int id;


//    @Column(name = "old")
    @Column(name = "bold")
    public int old;
}

Fully rebuild project, run app, hibernate logs seems fine as they show that old table was dropped, new table created, fields are named correctly but... Using localhost:8080/example?sort=bold leads to完全重建项目,运行应用程序,休眠日志似乎很好,因为它们显示旧表已删除,新表已创建,字段命名正确但是...使用 localhost:8080/example?sort=bold 会导致

org.springframework.data.mapping.PropertyReferenceException: No property 'bold' found for type 'Example'! Did you mean ''old''?

If you have an idea what's going on or at least have a tip where the issue comes from I would gladly listen and dive in answer如果您知道发生了什么,或者至少知道问题出在哪里,我很乐意倾听并深入回答

UPD UPD

After renaming field "old" to "bold" I found out that there is a problem with naming strategy, so I considered defining将字段“old”重命名为“bold”后,我发现命名策略有问题,所以我考虑定义

spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

in my application.properties, hoping it would help, but it didn't在我的 application.properties 中,希望它会有所帮助,但它没有

Is there any way?有什么办法吗?

UPD 2 Warning: in order to achieve results I achieved while debugging you need Hibernate 5.6.9, Spring 2.7.0, blank started app (you haven't made any requests involving your test-request yet, so there is nothing in request cache (except for id field)) .......... In short, you can directly jump to PropertyPath(String name, TypeInformation<?> owningType, List base), which is a constructor for PropertyPath class, executing logic of our program, in which we will fall in CachedIntrospectionResults::getPropertyDescriptor(String name) which checks that descriptor of our class has a corresponding field (this field's name equals to the sortBy parameter in our case), and, if field's name not same as sortBy parameter, we will not get our sorting or get it wrong (since it's another, not mentioned by us field) UPD 2警告:为了实现我在调试时取得的结果,您需要 Hibernate 5.6.9、Spring 2.7.0、空白启动的应用程序(您尚未发出任何涉及测试请求的请求,因此请求缓存中没有任何内容(id字段除外))............总之可以直接跳转到PropertyPath(String name, TypeInformation<?> owningType, List base),它是PropertyPath类的构造函数,执行逻辑在我们的程序中,我们将在 CachedIntrospectionResults::getPropertyDescriptor(String name) 中检查我们类的描述符是否具有相应的字段(在我们的例子中,此字段的名称等于 sortBy 参数),并且如果字段的名称不同作为 sortBy 参数,我们不会得到排序或出错(因为它是另一个,我们字段未提及)

Thus question is closed, no hope here因此问题已结束,这里没有希望

    package pckg;

import javax.persistence.*;

@Entity 
@Table(name = "example)
class Example {

    @Column(name = "id")
    public int id;


//    @Column(name = "old")
    @Column(name = "bold")
    public int old;
}

You missed a colon " in the @Table(name = "example) .您在@Table(name = "example)中遗漏了一个冒号"

Answer is actual for Hibernate 5.6.9, didn't check what's going on in another versions.答案对于 Hibernate 5.6.9 是实际的,没有检查其他版本中发生了什么。

Let us debug while executing our page request (repo.findAll(pageable))让我们在执行页面请求时进行调试 (repo.findAll(pageable))

Skipping all wrapper, calls and checks: in short, you can directly jump to PropertyPath(String name, TypeInformation<?> owningType, List base), which is a constructor for PropertyPath class, executing logic of our program, in which we will fall in CachedIntrospectionResults::getPropertyDescriptor(String name) which checks that descriptor of our class has a corresponding field (this field's name equals to the sortBy parameter in our case), and, if field's name not same as sortBy parameter, we will not get our sorting or get it wrong (since it's another, not mentioned by us field)跳过所有的包装器、调用和检查:总之可以直接跳转到PropertyPath(String name, TypeInformation<?> owningType, List base),它是PropertyPath类的构造函数,执行我们程序的逻辑,我们将落入其中在 CachedIntrospectionResults::getPropertyDescriptor(String name) 中,它检查我们类的描述符是否有相应的字段(在我们的例子中,这个字段的名称等于 sortBy 参数),如果字段的名称与 sortBy 参数不同,我们将不会得到我们的排序或弄错(因为它是另一个,我们领域没有提到)

Thus question is closed, no hope here因此问题已结束,这里没有希望

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM