Spring JPA无法在Kotlin数据类中使用自定义setter映射字段

时间:2017-08-14 02:00:24

标签: spring spring-data-jpa kotlin

我有一个带有自定义setter的Kotlin数据类。 Spring JPA框架似乎无法使用自定义setter映射属性。如果我删除自定义getter / setter并将属性重命名为return ( <td key={field._id} className={`oldField ${colPos}`} > <input type="text" defaultValue={value} onChange={this.changeOldField(record, field)} /> </td> ) 而不是login,则一切似乎都能正常工作。如何使用自定义setter在Kotlin数据类中创建属性,以便在JPA框架中识别它?

User.kt

_login

我得到的错误:

@Entity
@Table(name = "jhi_user")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
data class User (

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
    @SequenceGenerator(name = "sequenceGenerator")
    var id: Long? = null,

    @NotNull
    @Pattern(regexp = Constants.LOGIN_REGEX)
    @Size(min = 1, max = 50)
    @Column(name = "login", length = 50, unique = true, nullable = false)
    var _login: String? = null,

    @JsonIgnore
    @NotNull
    @Size(min = 60, max = 60)
    @Column(name = "password_hash",length = 60)
    var password: String? = null,

    ...

    @JsonIgnore
    @ManyToMany
    @JoinTable(
    name = "jhi_user_authority",
    joinColumns = arrayOf(JoinColumn(name = "user_id", referencedColumnName = "id")),
    inverseJoinColumns = arrayOf(JoinColumn(name = "authority_name", referencedColumnName = "name")))
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    @BatchSize(size = 20)
    var authorities: MutableSet<Authority>? = null): AbstractAuditingEntity(), Serializable {

    //Lowercase the login before saving it in database
    var login: String?
        get() = _login
        set(value) {
            _login = StringUtils.lowerCase(value, Locale.ENGLISH)
        }
}

1 个答案:

答案 0 :(得分:2)

对像这样的构造函数参数使用自定义setter有点难看(但遗憾的是我知道这样做的唯一方法)。

对于初学者来说,JPA将要将_login和login注册为数据库中的单独列,因为它们都不是@Transient。我相信你的问题出现在这里,因为你已经将_login属性标记为映射到“login”列,而login属性没有@Column注释,所以它试图映射到它的默认值“login”已经有_login属性映射到它。

因此,我认为您可能希望使_login瞬态并且只能持续登录(为了简洁和清晰,我错过了不相关的代码):

from collections import OrderedDict

def random_function(some_dict):
    first_key = list(some_dict.items())[0][0]
    first_value = list(some_dict.items())[0][1]
    print(first_key)
    print(first_value)

my_dictionary = OrderedDict({'first': 1, 'second': 2})
random_function(my_dictionary)
> first
> 1

如果这仍然不起作用,那么我真的认为这比使用JPA的构造函数属性上使用自定义setter的这个已经有点hacky的解决方案更值得麻烦。我建议在将它保存到数据库之前使用@ PrePersist / @ PreUpdate方法为您做小写。