Alejandro
Alejandro

Reputation: 826

Hibernate not properly building the query

My project is built with Spring Boot and Kotlin.

I have a class Message that might have a parent message (when responding a message), the code looks like this:

@Entity
class Message(
    @field: Id
    @field:GeneratedValue var id : Long = 0,

    @field: ManyToOne(targetEntity = Employee::class)
    var sender:Employee?=null,

    @field: ManyToOne(targetEntity = Employee::class)
    var receiver:Employee?=null,
    var time:LocalDateTime,
    var content: String,
    var read:Boolean,

    @field: ManyToOne(targetEntity = Message::class)
    @Nullable
    var father:Message?=null)
{}

when calling this query (using JpaRepository):

fun findByReceiverIdAndReadFalse(id:Long):List<Message>

I get this error:

Unknown column 'message0_.father_id' in 'field list'

It actually should be message0_.father.id, not father_id (father being the Message entity).

The full query built by Hibernate is this:

select
        message0_.id as id1_5_,
        message0_.content as content2_5_,
        message0_.father_id as father_i5_5_,
        message0_.read as read3_5_,
        message0_.receiver_id as receiver6_5_,
        message0_.sender_id as sender_i7_5_,
        message0_.time as time4_5_ 
    from
        message message0_ 
    left outer join
        employee employee1_ 
            on message0_.receiver_id=employee1_.id 
    where
        employee1_.id=? 
        and message0_.read=0

Employee class:

@Entity
data class Employee(
    @field: Id
    @field:GeneratedValue var id : Long = 0,
    var username : String = "",
    var password : String ="",
    var name : String ="",
    var lastName: String ="",
    var phone : String="",
    var email : String ="",
    var sex : String ="",
    var active : Boolean = false,
    @field: ManyToOne(targetEntity = District::class)
    var district : District? = null,
    @field: ManyToOne(targetEntity = Company::class)
    var company : Company? = null,
    var picture:String="",
    var resetPasswordCode:String="",
    // código que se le envía al usuario en el momento que crea
    // la cuenta, deberá abrir en enlace del correo para activarla
    // de ahí que "active" sea false.
    var activationCode : String="",
    // La fecha en que caduca el código activación: 5 días para activar
    var activationCodeExpiration : LocalDateTime = LocalDateTime.now().plusDays(5),
    var enabled : Boolean = true,
    var accountNonExpired: Boolean = true,
    var credentialsNonExpired: Boolean = true,
    var accountNonLocked : Boolean = true,
    @field: OneToMany(targetEntity = Roles::class) var roles :MutableSet<Roles> = mutableSetOf())

{
    fun toUser() : User
    {
        val authorities = mutableSetOf<GrantedAuthority>()
        roles.forEach{authorities.add(SimpleGrantedAuthority(it.role))}
        return 
User(username,password,enabled,accountNonExpired,credentialsNonExpired,accountNonLocked, authorities)
    }
}

Is there any way to force using the proper fields? Am I missing something?

Upvotes: 0

Views: 106

Answers (1)

asm0dey
asm0dey

Reputation: 2931

The problem is there is no @JoinColumn annotation on field father. Join column says JPA which column in DB (not field!) is referencing our current entity, while targetEntity says JPA (and that's completely obsolete as of me) which class represents our current field.

Upvotes: 1

Related Questions