【问题标题】:Kotlin Exposed create entity with referenceKotlin Exposed 使用引用创建实体
【发布时间】:2021-05-12 12:23:05
【问题描述】:

我正在尝试在 Kotlin 上使用 Exposed 编写 CRUD 服务。我有一张包含多对一参考的表格。当我尝试插入时,我得到了

java.lang.IllegalStateException: 上下文中没有事务。

这是表格和实体

object Contacts : IntIdTable("ph_contact"){
    var firstName = varchar("first_name",255)
    var lastName = varchar("last_name",255)
    var phone = varchar("phone",4096)
    var email = varchar("email",4096)
    var user = reference("user",Users)
}

class ContactEntity (id: EntityID<Int>): IntEntity(id){
    companion object : IntEntityClass<ContactEntity>(Contacts)

    var firstName by Contacts.firstName
    var lastName by Contacts.lastName
    var phone by Contacts.phone
    var email by Contacts.email
    var user by UserEntity referencedOn Contacts.user


    fun toContact() = Contact(id.value,user.id.value,firstName,lastName,phone,email)

}


data class Contact(
    val id: Int,
    val userId: Int,
    val firstName: String,
    val lastName: String,
    val phone: String,
    val email: String
)

这里是创建的服务方法

fun createContact(contact: Contact) = transaction {

        ContactEntity.new {

           this.firstName=contact.firstName
           this.lastName=contact.lastName
           this.phone=contact.phone
           this.email=contact.email
           this.user= UserEntity[contact.userId]

        }
    }

保存实体后调用toContact()方法报错

var contact = contactEntity.toContact()

创建此类实体的正确方法是什么?

【问题讨论】:

    标签: kotlin kotlin-exposed


    【解决方案1】:

    您需要在 create 方法的事务中调用 toContact 方法。

    记录的嵌套用户记录只能从事务内部懒惰地访问。

    我通过让任何数据访问层接口使用我自己的数据类来解决这个问题。暴露的记录和表在该层下保持私有。不要让事务实体在其上方泄漏。

    下面的例子用一个嵌套的用户来说明:

    object Users : IntIdTable("ph_users") {
        var otherUserData = varchar("other_user_data", 255)
    }
    
    class UserEntity(id: EntityID<Int>) : IntEntity(id) {
        companion object : IntEntityClass<UserEntity>(Users)
    
        var otherUserData by Users.otherUserData
    
    
        fun toUser() = User(id.value, otherUserData)
    
    }
    
    object Contacts : IntIdTable("ph_contact") {
        var firstName = varchar("first_name", 255)
        var lastName = varchar("last_name", 255)
        var phone = varchar("phone", 4096)
        var email = varchar("email", 4096)
        var user = reference("user", Users)
    }
    
    class ContactEntity(id: EntityID<Int>) : IntEntity(id) {
        companion object : IntEntityClass<ContactEntity>(Contacts)
    
        var firstName by Contacts.firstName
        var lastName by Contacts.lastName
        var phone by Contacts.phone
        var email by Contacts.email
        var user by UserEntity referencedOn Contacts.user
    
        fun toContact() = Contact(id.value, user.toUser(), firstName, lastName, phone, email)
    }
    
    
    data class Contact(
        val id: Int,
        val user: User,
        val firstName: String,
        val lastName: String,
        val phone: String,
        val email: String
    )
    
    data class User(
        val id: Int,
        val otherUserData: String
    )
    
    class ContactsRepo {
    
        fun createContact(contact: Contact): Contact = transaction {
            ContactEntity.new {
                this.firstName = contact.firstName
                this.lastName = contact.lastName
                this.phone = contact.phone
                this.email = contact.email
                this.user = UserEntity[contact.user.id]
    
            }.toContact()
        }
    
    }
    

    编辑:另一种方法是不使用引用的用户记录,而是将其保留为用户 ID?但可能您在其他查询中需要此嵌套记录。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-27
      • 2020-06-20
      • 1970-01-01
      • 2023-01-21
      • 2019-04-15
      • 1970-01-01
      • 2018-01-11
      • 2022-12-15
      相关资源
      最近更新 更多