Delegated classes and JPA/Hibernate

I’m trying to compose a JPA entity using class delegation (in a java+kotlin project) with no avail. I have something like this:

interface TestTrait : Serializable {
    var traitValue: Int
}

@MappedSuperclass
open class TestTraitImpl : TestTrait {
    override var traitValue: Int = 0
}

@MappedSuperclass
class TestMixin :
        TestTrait by TestTraitImpl() {
    var mixinValue: Int = 0
}

@Entity
@Table
public class TestEntity extends TestMixin {

    @Id
    @GeneratedValue
    @Type(type = "uuid-char")
    private UUID id;

    private int entityValue;

    public int getEntityValue() {
        return entityValue;
    }

    public void setEntityValue(int entityValue) {
        this.entityValue = entityValue;
    }
}

Both entityValue and mixinValue are processed by Hibernate correctly, but traitValue is not. Is class delegation fully supported by Hibernate/JPA? Am I missing something?

I can see that TestEntity has a $$delegate_0 attribute, but Hibernate seems to ignore it. Is there some annotation I need to add to my TestTrait or TestTraitImpl so it can be processed by Hibernate?

Hi @totaltabardo, I think using Reflection instead of a annotation would work better with Hibernate.

Hi @miker256, thanks for the reply! Any idea on where to start? I’m not an expert on reflection by any means, but I have used it a few times in the pass to circumvent restrictions in libraries (similar to the problem here). In this case though, I’m trying to get my head around on how can I use reflection to solve this problem and I can’t think of anything. I’ll give it more thought and keep researching as I might have an eureka moment.

Found the solution!
It’s obvious now, but the problem was that I was using JPA field annotation instead of accessor. It all made sense after having a look at the bytecode that Kotlin was generating for the TestMixin class.

This is the updated solution:

interface TestTrait {
    @get:Column
    var traitValue: Int
}

class TestTraitImpl : TestTrait {
    override var traitValue: Int = 0
}

@MappedSuperclass
class TestMixin :
        TestTrait by TestTraitImpl() {
    @get:Column
    var mixinValue: Int = 0
}

@Entity
@Table
public class TestEntity extends TestMixin {

    private UUID id;
    private int entityValue;

    @Id
    @GeneratedValue
    @Type(type = "uuid-char")
    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    @Column
    public int getEntityValue() {
        return entityValue;
    }

    public void setEntityValue(int entityValue) {
        this.entityValue = entityValue;
    }
}

I always preferred field annotation over accessor, but being able to use composition on my JPA entities is much more important!