【问题标题】:Spring Data JPA / Hibernate "Unable to locate Attribute with the given name"Spring Data JPA / Hibernate“无法找到具有给定名称的属性”
【发布时间】:2017-01-13 14:24:15
【问题描述】:

Spring Web 应用程序和 Hibernate 存在问题。它是用 Kotlin 编写的。 我们有一个抽象实体

@Inheritance(strategy = InheritanceType.JOINED)
abstract @Entity class ContactLogEntry protected constructor() {

    @GeneratedValue @Id val id: Long = 0


    @ManyToOne
    @JoinColumn
    protected lateinit var _contact: AbstractContact
    open val contact: AbstractContact? get() = _contact

  @ManyToOne
    protected var _user: User? = null
    open val user: User? get() = _user

还有一些:

@Entity class MailLogEntry() : ContactLogEntry() {


    override var contact: Lead
        get() = super.contact as Lead
        set(value) {
            super._contact = value
        }

 override var user: Telephonist
        get() = super.user as Telephonist
        private set(value) {
            super._user = value
        }

请注意,“Lead”直接继承自“AbstractContact”。问题在于属性contact。 Telephonist 直接从 User 继承的 User 属性工作正常。

我们得到Unable to locate Attribute with the the given name [contact] on this ManagedType (PATH to ContactLogEntry)

我们以前也是这样做的,它在哪里起作用。真的不知道有什么问题。

【问题讨论】:

  • 我知道已经 3 年了,但是你有没有成功解决这个问题?我现在偶然发现了这一点。我不能将继承与 TABLE_PER_CLASS 一起使用,因为它需要我在子类中定义 Id..

标签: java spring hibernate spring-mvc kotlin


【解决方案1】:

在我的情况下,使用纯java,原因是抽象的@MappedSuperClass根据接口定义了抽象的getter/setter方法,但没有定义实际的成员字段。

从抽象类中删除 getter/setter 方法后错误消失了,毕竟不需要它们。高温

【讨论】:

    【解决方案2】:

    更广泛的可能性是您重构了一个属性名称,但在以下方面存在不一致:

    • getter 和/或 setter
    • @查询
    • @NamedEntityGraphs
    • @NamedQuery

    【讨论】:

    • 在我的例子中是@NamedEntityGraph
    【解决方案3】:

    此答案仅适用于 Kotlin。

    如果是依赖 getter 和 setter 访问但默认设置为字段访问的情况,更改访问类型也可以解决错误(在我的情况下确实如此)。

    • 使用@Access(AccessType.PROPERTY) 以便使用getter 和setter。

    • 使用@Access(AccessType.FIELD) 以便使用该字段本身。

    正如this helpful article 中更详细的解释:

    默认情况下,您通过注解隐式指定访问策略 您的主键属性或其带有 @Id 的 getter 方法 注解。如果您注释属性本身,Hibernate 使用 基于字段的访问。

    [...] 如果你用 @Id注解,Hibernate使用基于属性的访问来设置和读取 该实体的属性。

    覆盖默认访问策略

    如果您想在一个实体或一个实体中混合使用两种访问策略 实体的层次结构,您需要覆盖默认策略 @Access 注释。

    示例

    在 Java 中:

    @Access(AccessType.PROPERTY)
    public User getUser() { return user; }
    

    另外,我认为在 OP 的情况下,使用泛型可以让它变得不那么复杂:

    @Inheritance(strategy = InheritanceType.JOINED)
    @Entity
    abstract class ContactLogEntry<Contact: AbstractContact, UserT: User>
            protected constructor() {
        @GeneratedValue @Id val id: Long = 0
    
        @ManyToOne
        @JoinColumn
        open var contact: Contact? = null
    
        @ManyToOne
        open var user: UserT? = null
    }
    
    @Entity class MailLogEntry : ContactLogEntry<Lead, Telephonist>()
    

    【讨论】:

      猜你喜欢
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-15
      • 2015-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多