Kotlin: Collection has neither generic type or One

2020-06-30 06:03发布

问题:

I have an Enum class RoleType

public enum RoleType {
    SYSTEM_ADMIN, PROJECT_ADMIN, USER;
}

In my User entity class, I've the following mapping for the enum collection. This is the Java code:

@JsonProperty
@ElementCollection
@Enumerated(EnumType.STRING)
@CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"))
private Set<RoleType> roles;

I converted this User entity class to Kotlin and here is the code:

@JsonProperty
@Enumerated(EnumType.STRING)
@ElementCollection
@CollectionTable(name = "user_role", joinColumns = arrayOf(JoinColumn(name = "user_id")))
var roles: kotlin.collections.Set<RoleType>? = null

After the conversion, hibernate is throwing the following exception:

Collection has neither generic type or OneToMany.targetEntity() defined: com.a.b.model.User.roles

It was working fine before in Java.

I also tried adding the targetClass in @ElementCollection like this:

@ElementCollection(targetClass = RoleType::class)

but it's also throwing another exception.

Fail to process type argument in a generic declaration. Member : com.a.b.model.User#roles Type: class sun.reflect.generics.reflectiveObjects.WildcardTypeImpl
ERROR [2017-05-27 04:46:33,123] org.hibernate.annotations.common.AssertionFailure: HCANN000002: An assertion failure occurred (this may indicate a bug in Hibernate)
! org.hibernate.annotations.common.AssertionFailure: Fail to process type argument in a generic declaration. Member : com.a.b.model.User#roles Type: class sun.reflect.generics.reflectiveObjects.WildcardTypeImpl

Note: If i change the modifier of roles from var to val, it's working, but i need this to be a mutable type. I don't understand how the mutability of a field is creating issues in hibernate.

Note: I'm using Kotlin 1.1.2-2 & Hibernate 5.2 version.

回答1:

Have you tried changing

var roles: Set<RoleType>? = null

to

var roles: MutableSet<RoleType>? = null

If you have a look at the interface definition of Set, you'll see it's defined as public interface Set<out E> : Collection<E> whereas MutableSet is defined as public interface MutableSet<E> : Set<E>, MutableCollection<E>

Set<out E> 's Java equivalent I believe is Set<? extends E> instead of what you were looking for Set<E>.