【问题标题】:How can a UUID be shared as a primary key in two tables using Hibernate?如何使用 Hibernate 在两个表中将 UUID 共享为主键?
【发布时间】:2017-10-06 21:09:22
【问题描述】:

我使用 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: @OneToOne 或 @ManyToOne on Entities.UserLogin.userId 引用了一个未知实体:java.util.UUID

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

请告诉我为什么会收到错误消息?如果我能够将 UUID 以二进制 (16) 形式存储在数据库中?

【问题讨论】:

    标签: java mysql hibernate kotlin


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      • 首先,我使用了 mappedBy 错误。 mappedBy 的值必须是类中的一个字段或类的名称,名称以小写开头。我使用的是实际表中的列名。

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

      • 第三,德克斯特是对的。 @OneToOne 只能用于实体。

      • 第四,我没有在 DB 的表中放置约束。

        好消息是 UUID 转二进制有效!耶!!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-02
        • 2018-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-23
        • 1970-01-01
        相关资源
        最近更新 更多