【问题标题】:JPA/Hibernate manyToMany relation mapping with additional fields带有附加字段的 JPA/Hibernate 多对多关系映射
【发布时间】:2018-11-22 17:44:32
【问题描述】:

我有 manyToMany 关系映射,但无法正常工作。我已经阅读了很多帖子和文章,但无法弄清楚这一点。如果有人有什么想法,请分享。

我尽量简化图表和代码。

我的数据库是这样设计的:

我的实体看起来像这样(至少在询问之前的最后一次尝试):
客户:

@Entity
@Table(name = "client")
public class Client implements Serializable {
    @Id
    @Column(name = "client_id")
    private int id;

    ... other fields
}

项目:

@Entity
@Table(name = "project")
public class Project implements Serializable {
    @EmbeddedId
    private ProjectId id;

    ... other fields

    @Embeddable
    class ProjectId implements Serializable {
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "client_id", insertable = false, updatable = false)
        private Client client;

        @Column(name = "project_id")
        private int projectId;
    }
}

用户:

@Entity
@Table(name = "user")
public class User implements Serializable {
    @EmbeddedId
    private UserId id;

    ... other fields

    @Embeddable
    class UserId implements Serializable {
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "client_id", insertable = false, updatable = false)
        private Client client;

        @Column(name = "user_id")
        private int userId;
    }
}

项目用户:

@Entity
@Table(name = "project_user")
public class ProjectUser implements Serializable {
    @EmbeddedId
    private ProjectUserId id;

    ... other fields

    @Embeddable
    class ProjectUserId implements Serializable {
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "client_id", insertable = false, updatable = false)
        private Client client;

        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumns({
            @JoinColumn(name = "client_id", referencedColumnName = "client_id", insertable = false, updatable = false),
            @JoinColumn(name = "project_id", referencedColumnName = "project_id", insertable = false, updatable = false) })
        private Project project;

        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumns({
            @JoinColumn(name = "client_id", referencedColumnName = "client_id", insertable = false, updatable = false),
            @JoinColumn(name = "user_id", referencedColumnName = "user_id", insertable = false, updatable = false) })
        private User user;
    }
}

在添加 ProjectUser 实体之前,一切正常。
现在,当我启动服务器时,它说:

实体映射中的重复列:ProjectUser 列:client_id (应该用 insert=\"false\" update=\"false\")"}}

映射

那么,问题是我该如何完成这项工作?

编辑: Java 应用程序将主要由 REST 服务提供数据。数据库设计原样。它具有逻辑意义,大部分业务逻辑都在数据库中。我们有具有非常好的数据库知识的人从事这方面的工作,由于 JPA/Hibernate 的限制,改变数据库设计没有多大意义。

【问题讨论】:

  • 从重新设计架构开始。这对我来说真的没有任何意义。例如,您有 ProjectId 的 Project,因此您不将 clientId 作为主键的一部分。与用户相同。 project_user 想告诉你什么?如果它只是应该将用户映射到项目和项目到用户很好,那么 clientId 是什么?这一切看起来就像您从多对多开始并添加了 Client 并将 clientId 粘贴到所有内容中。首先在更抽象的层次上定义你想要做什么。
  • 我已经编辑了原始问题以进行澄清。感谢您的建议,但我真的很想知道这是否可以使用当前数据库模式进行映射。
  • “我们有拥有非常好的数据库知识的人在做这方面的工作”——或者没有。我可以想象用 JPA 来做这件事,但它仍然没有意义,所以不值得。

标签: java hibernate jpa many-to-many


【解决方案1】:

下面的代码会让 hibernate 为你的实体创建一个结构:

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "client_id", insertable = false, updatable = false)
    private Client client;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns({
            @JoinColumn(name = "project_client_id", referencedColumnName = "client_id", insertable = false, updatable = false),
            @JoinColumn(name = "project_id", referencedColumnName = "project_id", insertable = false, updatable = false) })
    private Project project;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns({
            @JoinColumn(name = "user_client_id", referencedColumnName = "client_id", insertable = false, updatable = false),
            @JoinColumn(name = "user_id", referencedColumnName = "user_id", insertable = false, updatable = false) })
    private User user;

但是要按照您问题中的图片制定方案,请摆脱所有这些EmbeddedId。如果您希望 ProjectUser 中的项目和用户具有相同的 client_id,请使用简单的 id 并在代码中添加验证。

【讨论】:

  • 感谢您的回答。我已经编辑了原始问题以进行澄清。您添加另外两个字段的解决方案适用于休眠,但添加字段似乎只是为了满足休眠。因此,根据当前的数据库情况,似乎没有办法对此进行映射。也许是时候重新考虑其他一些持久性解决方案了。
  • @hyperion385 当然你可以映射这个!你只需要摆脱EmbeddedId,使用简单的ID。
  • 嗯,是的,这就是我今天所做的。但不知何故,我觉得整个对象映射失去了它的目的。但总比不工作要好:)
猜你喜欢
  • 2016-03-04
  • 2021-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-13
  • 1970-01-01
  • 2014-03-29
相关资源
最近更新 更多