提问者:小点点

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


我遇到过一个问题,Spring看不到@Entity的新@列名

我运行的确切示例:

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);
}

其余代码是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: _*)
  }
}

应用程序属性

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

我构建并运行此代码,使用浏览器进行测试,在endpoint上使用参数ort="old"发出localhost:8080/example请求,如下所示:localhost:8080/example?sort=old

然后我将@Column name从“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;
}

完全重建项目,运行应用程序,Hibernate日志似乎很好,因为它们显示旧表已被删除,新表已创建,字段命名正确,但...使用 localhost:8080/example?sort=bold 会导致

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

如果你知道发生了什么,或者至少知道了问题的来源,我会很乐意倾听并回答

UPD

将字段“旧”重命名为“粗体”后,我发现命名策略有问题,所以我考虑定义

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

我application.properties希望能有所帮助但没有

有什么办法吗?

UPD 2警告:为了达到我在调试时取得的结果,您需要Hibernate 5.6.9、Spring 2.7.0、空白启动的应用程序(您还没有提出任何涉及您的test-Request的请求,因此请求缓存中没有任何内容(id字段除外)).........总之,您可以直接跳转到属性路径(字符串名称,TypeInformation

因此,问题是封闭的,这里没有希望


共2个答案

匿名用户

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

您在@Table(name = “example)”中遗漏了冒号”。

匿名用户

答案是实际的Hibernate 5.6.9,没有检查其他版本的情况。

让我们在执行页面请求时进行调试(repo.findAll(pageable))

跳过所有包装器、调用和检查:简而言之,可以直接跳转到PropertyPath(String name,TypeInformation

因此,问题是封闭的,这里没有希望