'Spring Data JPA / Hibernate "Unable to locate Attribute with the given name"

We have a problem with a Spring Web Application and Hibernate. It is written in Kotlin. We have an abstract Entity

@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

And some of those:

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

Note that "Lead" inherits directly from "AbstractContact". The Problem is with the property contact. The User Property, where Telephonist inherits directly from User, works fine.

We get Unable to locate Attribute with the the given name [contact] on this ManagedType (PATH to ContactLogEntry)

We did it the same way before, where it works. Really no clue whats wrong.



Solution 1:[1]

In my case, using pure java, the cause was that an abstract @MappedSuperClass defined abstract getter/setter methods according to an interface, but did not define the actual member field.

The error went away after removing the getter/setter methods from the abstract class, there was no need for them after all. HTH

Solution 2:[2]

A wider possibility is that you refactorized an attribute name but with an inconsistency in a:

  • getter and/or setter
  • @Query
  • @NamedEntityGraphs
  • @NamedQuery

Solution 3:[3]

This answer applies only to Kotlin.

Changing the access type may solve the error also (in my case it did), if it is the case that one is relying on getter and setter access but the default has been set to field access.

  • Use @Access(AccessType.PROPERTY) in order for getter and setter to be used.

  • Use @Access(AccessType.FIELD) in order for the field itself to be used.

As explained in more detail in this helpful article:

By default, you specify the access strategy implicitly by annotating your primary key attribute or its getter method with an @Id annotation. If you annotate the attribute itself, Hibernate uses field-based access.

[...] And if you annotate a getter method with the @Id annotation, Hibernate uses property-based access to set and read the attributes of this entity.

Override the default access strategy

If you want to mix both access strategies within one entity or a hierarchy of entities, you need to override the default strategy with an @Access annotation.

Example

In Java:

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

Also, I think that in OP's case using Generics make it a little less complicated:

@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>()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Manos Batsis
Solution 2 Julio Villane
Solution 3