【问题标题】:JPA Mapping Issue - Modelling direction requestedJPA 映射问题 - 请求建模方向
【发布时间】:2011-03-27 08:48:36
【问题描述】:

我在 JPA 中对以下问题建模时遇到问题。我有一个 JPA 实体类“用户”,如下所示: (为简洁起见,省略了访问器/修改器/无关字段/无关 JPA 配置)


    @Entity
    class User {
        @Id
        @Generated Value
        long id;
        @OneToMany
        Report contributorReports; // All the reports where this user is contributor
        @OneToMany ownerReports; // All the reports where this user is owner
        String username;
    }

和一个 JPA 实体类“报告”


@Entity
class Report {
    @Id
    @GeneratedValue
    long id;
    @OneToOne
    User contributor;
    @OneToOne
    User owner;
    SomeData data;
}

我想建模这样的关系:

  • 报告必须同时包含贡献者和所有者
  • 我可以通过用户实体访问用户作为“贡献者”的所有报告
  • 我可以通过用户实体访问用户作为“所有者”的所有报告

我想我最终会得到一个看起来像这样的映射表:


CREATE TABLE user_report {
    BIGINT reportId,
    BIGINT contributorId,
    BIGINT ownerId,
}

我试图解决这个问题:


    @OneToOne
    @JoinTable(name = "user_report",
            joinColumns = {
                    @JoinColumn(name = "reportOwner_ID", referencedColumnName = "ID")}
            )
    private User owner;
    @OneToOne
    @JoinTable(name = "user_report",
            joinColumns = {
                @JoinColumn(name = "reportContributor_ID", referencedColumnName = "ID")}
            )
    private User contributor;

这会生成如下表格:

CREATE TABLE user_report (
    BIGINT ownerReport_ID, // Report ID
    BIGINT reportOwner_ID, // UserID owner
    BIGINT contributorReport_ID, // Report ID
    BIGINT reportContributor_ID // UserID contributor
)

所以当 JPA 尝试映射到这个表时,它会分别映射每个字段并失败,因为只有一半的行被提交,抛出这个异常:

Caused by: java.sql.BatchUpdateException: Field 'ownerReport_ID' doesn't have a default value

我希望就如何最好地模拟我所设想的关系获得一些指导。 (或者也许是一种更好的方式来设想这种关系)如果需要更多信息,我很乐意提供。

亲切的问候 马特

【问题讨论】:

  • 为什么在报表端使用@OneToOne,应该是@ManyToOne

标签: java database orm jpa eclipselink


【解决方案1】:

根据您的要求,我相信您可以通过从用户到报告的 2 个 1:M 来完成此任务,并且每个返回匹配的 M:1。

@Entity
class User {
    @Id
    @Generated Value
    long id;

    // All the reports where this user is contributor
    @OneToMany(mappedBy="contributor")
    List<Report> contributorReports; 

    // All the reports where this user is owner
    @OneToMany(mappedBy="owner")
    List<Report> ownerReports; 

    String username;
}

那么您的 Report 类将如下所示:

@Entity
class Report {
    @Id
    @GeneratedValue
    long id;

    @ManyToOne
    User contributor;

    @ManyToOne
    User owner;

    SomeData data;
}

连接表也可能出现这种情况,但据我了解,根据您的要求,这不是必需的。

道格

【讨论】:

  • 谢谢 Doug,这确实是我所需要的!为树木而生的森林等等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
相关资源
最近更新 更多