Kotlin公开了使用引用创建实体

Kotlin公开了使用引用创建实体,kotlin,kotlin-exposed,Kotlin,Kotlin Exposed,我正在尝试使用Exposed on Kotlin编写CRUD服务。我有一张多对一的桌子。当我尝试插入时,我得到 java.lang.IllegalStateException:上下文中没有事务 这是表和实体 object Contacts : IntIdTable("ph_contact"){ var firstName = varchar("first_name",255) var lastName = varchar("las

我正在尝试使用Exposed on Kotlin编写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
)
保存实体后调用toContact()方法时引发错误

var contact=contactEntity.toContact()


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

您需要在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()
    }

}
对象用户:可初始化(“PHU用户”){
var otherUserData=varchar(“其他用户数据”,255)
}
类UserEntity(id:EntityID):IntEntity(id){
伴随对象:IntEntityClass(用户)
var otherUserData by Users.otherUserData
fun-tuser()=用户(id.value,otherUserData)
}
对象触点:可初始化(“PHU触点”){
var firstName=varchar(“first_name”,255)
var lastName=varchar(“姓氏”,255)
var phone=varchar(“电话”,4096)
var email=varchar(“电子邮件”,4096)
var user=参考(“用户”,用户)
}
类ContactEntity(id:EntityID):意图(id){
伴生对象:IntEntityClass(联系人)
var firstName by Contacts.firstName
var lastName by Contacts.lastName
var phone by Contacts.phone
var通过Contacts.email发送电子邮件
var用户按用户实体在Contacts.user上引用
fun-toContact()=联系人(id.value,user.toUser(),firstName,lastName,电话,电子邮件)
}
数据类联系人(
val id:Int,
val用户:用户,
val firstName:String,
val lastName:String,
瓦尔电话:字符串,
val电子邮件:String
)
数据类用户(
val id:Int,
val otherUserData:字符串
)
类联系人{
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保存?但在其他查询中可能需要此嵌套记录。

您需要在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()
    }

}
对象用户:可初始化(“PHU用户”){
var otherUserData=varchar(“其他用户数据”,255)
}
类UserEntity(id:EntityID):IntEntity(id){
伴随对象:IntEntityClass(用户)
var otherUserData by Users.otherUserData
fun-tuser()=用户(id.value,otherUserData)
}
对象触点:可初始化(“PHU触点”){
var firstName=varchar(“first_name”,255)
var lastName=varchar(“姓氏”,255)
var phone=varchar(“电话”,4096)
var email=varchar(“电子邮件”,4096)
var user=参考(“用户”,用户)
}
类ContactEntity(id:EntityID):意图(id){
伴生对象:IntEntityClass(联系人)
var firstName by Contacts.firstName
var lastName by Contacts.lastName
var phone by Contacts.phone
var通过Contacts.email发送电子邮件
var用户按用户实体在Contacts.user上引用
fun-toContact()=联系人(id.value,user.toUser(),firstName,lastName,电话,电子邮件)
}
数据类联系人(
val id:Int,
val用户:用户,
val firstName:String,
val lastName:String,
瓦尔电话:字符串,
val电子邮件:String
)
数据类用户(
val id:Int,
val otherUserData:字符串
)
类联系人{
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保存?但在其他查询中可能需要此嵌套记录