【问题标题】:How to convert tables into Spring Data entities?如何将表转换为 Spring Data 实体?
【发布时间】:2019-11-20 07:59:25
【问题描述】:

我正在寻求将下表转换为 Spring 数据实体的帮助。我有点能做到,但我不知道强制删除和更新约束。我有一个包含用户信息的用户表。然后,对话表将有一个对话 id 和 2 列来代表参与用户的两个 id。我正在用 Kotlin 编写我的解决方案,但我也可以用 Java 提供建议。使用 Postgres。归根结底,我只想得到这两个表,它们能够更改用户表中的主键并将其转移到对话表中。

CREATE TABLE users (
    id uuid PRIMARY KEY,
    bio character varying(255),
    first_name character varying(255) NOT NULL,
    last_name character varying(255) NOT NULL,
    password character varying(255) NOT NULL,
    username character varying(255) NOT NULL UNIQUE,
    zip_code character varying(255) NOT NULL
);

CREATE TABLE conversations (
    convoid BIGSERIAL PRIMARY KEY,
    user_id1 uuid REFERENCES users(id) on delete cascade on update cascade,
    user_id2 uuid REFERENCES users(id) on delete cascade on update cascade
);

这是我尝试过的:

@Data
@NoArgsConstructor
@Entity
@Table(name = "users")
data class User(

        @Id //primary key
        var id: UUID = UUID.randomUUID(),

        @Column(nullable = false)
        var firstName: String,

        @Column(nullable = false)
        var lastName: String,

        @Column(nullable = false, unique = true)
        var username: String,

        @Column(nullable = false)
        var password: String,

        @Transient 
        var confirmPassword: String,

        @Column(nullable = false)
        var zipCode: String,

        @Column(nullable=true)
        var bio: String?

)

@Data
@NoArgsConstructor
@Entity
@Table(name = "conversations")
data class Conversation(

        @Id //primary key
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        val convoID: Long,

        @ManyToOne(cascade = [CascadeType.ALL])
        @JoinColumn(name = "user_id1")
        val user1: User, //FK of user table PK

        @ManyToOne(cascade = [CascadeType.ALL])
        @JoinColumn(name = "user_id2")
        val user2: User, //FK of user table PK

        @Transient
        var participants: List<WebSocketSession>

)

我正在尝试更新用户表中的主键,但由于外键约束,它不允许我这样做。显然 Cascade 无法正常工作。

【问题讨论】:

  • Intellij 有一个工具。转到持久性选项卡,您可以从表中创建实体类。但是你必须自己添加你的外键
  • Hrrmm 我知道一些 JPA 提供程序(例如 Hibernate)不允许您更改主键

标签: java spring-boot kotlin spring-data-jpa spring-data


【解决方案1】:

在 JPA 关系中仅以一种方式起作用,在其他情况下,要在删除 User 时删除 Converation,您需要从 UserConveration 建立 @OneToMany 关系。同样的事情也适用于更新。

所以在User 中添加这样的属性应该可以解决您的问题:

@OneToMany(cascade = CascadeType.ALL)
val conversations: List<Conversation>  

更新

JPA 创建单独的表,通常通过将 mappedBy = "mappingFieldName" 添加到 @OneToMany 来解决,但考虑到您有 2 个字段的情况,这有点棘手,而且问题更广泛。您要么必须进行大量自定义查询,要么只保留重复条目,这意味着对于每个新对话,您实际上将有 2 个,因此您可以说 mappedBy = "user1",只需记住每次保存 2 个对话,1其中 user1 是实际的 user1,另一个是您交换 user1 和 user2 的位置。

【讨论】:

  • 我刚刚添加了这个,它最终在数据库中创建了一个名为 user_conversations 的第三个表。嗯
猜你喜欢
  • 2013-03-06
  • 2018-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2020-02-21
  • 2018-01-19
相关资源
最近更新 更多