繁体   English   中英

如何使用Hibernate在两个表中将UUID作为主键共享?

[英]How can a UUID be shared as a primary key in two tables using Hibernate?

我将MySql用作数据库,旨在以Binary(16)格式存储生成的UUID。 在数据库中,我有两个表:

  1. 存储用户的详细信息。
  2. 存储用户密码。

我有两个实体UserDetails和UserLogin分别代表这些表。 它们如下:

UserDetails类:

package Entities

import org.hibernate.annotations.GenericGenerator
import org.hibernate.annotations.Type
import java.io.Serializable
import java.util.*
import javax.persistence.*

/**
 * class UserDetails
 */
@Entity
@Table(name = "user_details")
data class UserDetails(
        /**
         * The first name field for the user details table.
         */
        @Column(name = "first_name") var firstName: String,
        /**
         * The last name field for the user details table.
         */
        @Column(name = "last_name") var lastName: String,
        /**
         * The phone number field for the user details table.
         */
        @Column(name = "phone_number") var phoneNumber: String,
        /**
         * The area code field for the user details table.
         */
        @Column(name = "area_code") var areaCode: String,
        /**
         * The rating field for the user details table.
         */
        @Column(name = "rating") var rating: Double,
        /**
         * The user login information containing the password for the user.
         */
        @OneToOne(cascade = arrayOf(CascadeType.ALL), mappedBy = "user_id") @PrimaryKeyJoinColumn
        var userLogin: UserLogin
): Serializable {

    /**
     * The UserId field for the user details table.
     */
    @Id @Type(type = "uuid-binary")
    @GeneratedValue(generator = "uuid2") @GenericGenerator(name = "uuid2", strategy = "uuid2")
    @Column(name = "user_id") lateinit var userId: UUID

    @Suppress("unused")
    constructor() : this("", "", "", "", 0.0, UserLogin())

    companion object {
        @JvmStatic val serialVersionUID: Long = 1L
    }
}

UserLogin类别:

package Entities

import java.io.Serializable
import java.util.*
import javax.persistence.*

/**
 * class UserLogin
 *
 * This table is supposed to be temporary. The frontend has to run on mobile devices which will be using the OTP through
 * SMS to login to the app. Once that is done there is no need for this table and can be safely deleted w/o having to
 * modify a huge user_details table.
 *
 * @author niksinghal
 */
@Entity
@Table(name = "user_login_details")
data class UserLogin(
        /**
         * The password field for the login table.
         * It has to store the encrypted password.
         */
        @Column(name = "password", nullable = false) var password: String
): Serializable {

    /**
     * The user ID field for the login table.
     * This value is a shared primary key and it is populated by the UserDetails.userId field
     */
    @Id @OneToOne lateinit var userId: UUID

    @Suppress("unused")
    constructor() : this("")

    companion object {
        @JvmStatic val serialVersionUID: Long = 1L
    }
}

目的是为每个用户详细信息行(OneToOne映射)具有一个密码,并且为主键userId具有相同的值。

我正在编译它并得到- 调用init方法失败; 嵌套异常是org.hibernate.AnnotationException:Entities上的@OneToOne或@ManyToOne。UserLogin.userId引用了一个未知实体:java.util.UUID

我对此很陌生,并严格执行所有这些操作以学习Hibernate概念。 话虽如此,我的理解是UserDetails类的userId将由生成器生成。 UserDetails的UserLogin上方的@OneToOne和@PrimaryKeyJoinColumn批注应将生成的UUID推送到UserLogin的userId,该用户标识再次由@OneToOne标记。

请让我知道为什么会出现错误? 而且是否能够将UUID存储为DB中的binary(16)?

OneToOne批注用于关联整个实体,而不是单个值。 您需要告诉Hibernate它应该如何生成您的密钥。

现有的SOF线程可以回答您的问题。 例如这个线程

我在这里做错了很多事情:

  • 首先,我在使用mappedBy时出错。 MapledBy的值必须是类中的字段或类名,且名称以小写字母开头。 我在实际表中使用了列名。

  • 其次,我试图在两个表之间实现单向1-1关系(我稍后会学到这一点)。 目的是共享主键。 必须使用UserDetails类中userLogin上的@OneToOne和@PrimaryKeyJoinColumn批注来完成。

  • 第三,德克斯特是正确的。 @OneToOne只能在实体上使用。

  • 第四,我没有在数据库表中放置约束。

    好消息是,UUID可以二进制运行! 好极了!!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM