当前位置: 首页 > 知识库问答 >
问题:

JPA连接有两个字段的表,其中一个是主键

牟嘉
2023-03-14

问题是@ManyToOne@Joincolumn ID_REPORT(它是一个主键)和@Joincolumn ID_TEMPLATE_DEFAULT

实体映射中的重复列:CurReport 列:id_report(应使用插入=“false”更新=“false”进行映射)

代码

第一桌CUR_TEMPLATE

CREATE TABLE CUR_TEMPLATE 
   (    
    ID_REPORT NUMBER(5,0) NOT NULL, 
    ID_TEMPLATE NUMBER(5,0) NOT NULL, 
    -- Other fields
   );
 
ALTER TABLE CUR_TEMPLATE ADD CONSTRAINT PK_CUR_TEMPLATE PRIMARY KEY (ID_REPORT, ID_TEMPLATE)

-- CUR_TEMPLATE foreign keys
ALTER TABLE CUR_TEMPLATE ADD CONSTRAINT FK_CUR_PLAN_REFERENCE_CUR_REPO FOREIGN KEY (ID_REPORT)
      REFERENCES CUR_REPORTS (ID_REPORT);

第二个表CUR_REPORTS


-- CUR_REPORTS definition
CREATE TABLE CUR_REPORTS 
   (    
    ID_REPORT NUMBER(3,0) NOT NULL, 
    NAME_REPORT VARCHAR2(100) NOT NULL, 
    -- other fields 
    ID_TEMPLATE_DEFAULT NUMBER(5,0), 
    -- other fields
   ) ;

ALTER TABLE CUR_REPORTS ADD CONSTRAINT PK_CUR_REPORTS PRIMARY KEY (ID_REPORT)

ALTER TABLE CUR_REPORTS CONSTRAINT FK_CUR_REPO_REFERENCE_CUR_PLAN FOREIGN KEY (ID_REPORT, ID_TEMPLATE_DEFAULT)
      REFERENCES CUR_TEMPLATE (ID_REPORT, ID_TEMPLATE) 

第一个表CUR_REPORTS实体当前报表


@Entity
@Table(name = "CUR_REPORTS")
@IdClass(CurPlantillaPK.class)
@Getter
@Setter
public class CurReport {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID_REPORT", nullable = false)
    private Long id;

    @Column(name = "NAME_REPORT", nullable = false, length = 100)
    private String nombreReporte;

    @ManyToOne(fetch = FetchType.LAZY) <---WHERE IS THE PROBLEM 
    @JoinColumn(name = "ID_REPORT", referencedColumnName = "ID_REPORTE")
    @JoinColumn(name = "ID_TEMPLATE_DEFAULT", referencedColumnName = "ID_TEMPLATE")
    private CurTemplate curTemplate;

    @OneToMany(mappedBy = "curReport")
    private Set<CurTemplate> curTemplates= new LinkedHashSet<>();
}

第二个表CUR_TEMPLATE实体CurReport


@Entity
@Table(name = "CUR_TEMPLATE")
@IdClass(CurPlantillaPK.class)
@Getter
@Setter
public class CurTemplate {
    
    @Id
    @Column(name = "ID_REPORT", nullable = false)
    private Long idReport;

    @Id
    @Column(name = "ID_TEMPLATE", nullable = false)
    private Long idTemplate;

    
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_REPORT", foreignKey = @ForeignKey(name = "FK_CUR_PLAN_REFERENCE_CUR_REPO"), referencedColumnName = "ID_REPORT", insertable = false, updatable = false)
    private CurReport curReport;

}

当我添加可插入=假时,可更新=假

@JoinCollie(name="ID_REPORT",参考列名="ID_REPORT",可插入=false,可更新=false)

不允许在属性中混合可插入列和不可插入列:CurTemplate

我怎么能映射这些关系?当 FK 的一个字段为 PK 列时,如何解析@JoinColumn?

共有1个答案

袁卓
2023-03-14

您可以使用派生的标识并映射 CurTemplate,如下所示:

@Entity
@Table(name = "CUR_TEMPLATE")
@IdClass(CurTemplatePK.class)
@Getter
@Setter
public class CurTemplate {

    @Id
    @Column(name = "ID_TEMPLATE", nullable = false)
    private Long idTemplate;

    @Id
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_REPORT", foreignKey = @ForeignKey(name = "FK_CUR_PLAN_REFERENCE_CUR_REPO"), referencedColumnName = "ID_REPORT", insertable = false, updatable = false)
    private CurReport curReport;

}

然后您将需要一个这样的@IdClass

public class CurTemplatePK {
    Long idTemplate; // matches name of @Id attribute
    Long curReport; // matches name of @Id attribute and type of CurReport PK
}

然后,您应该为默认模板键使用基本映射,并为默认模板对象提供getter:

@Entity
@Table(name = "CUR_REPORTS")
@IdClass(CurPlantillaPK.class)
@Getter
@Setter
public class CurReport {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID_REPORT", nullable = false)
    private Long id;

    @Column(name = "NAME_REPORT", nullable = false, length = 100)
    private String nombreReporte;

    @Column(name = "ID_TEMPLATE_DEFAULT")
    private Long idDefaultTemplate;

    @OneToMany(mappedBy = "curReport")
    private Set<CurTemplate> curTemplates= new LinkedHashSet<>();

    public CurTemplate getDefaultTemplate() {
        return this.curTemplates.stream()
                .filter(template -> template.getIdTemplate().equals(idDefaultTemplate))
                .findFirst()
                .orElse(null);
    {
}

如果您想允许客户端设置默认模板,您将需要实现一个setter,该setter首先验证新的默认模板是否已经在setcurTemplate中。

 类似资料:
  • 试图确定是否可以创建一个连接表的查询,表一比表二小,表二有多个匹配表一条目的引用,查询将输出一个连接,其中表一的长度保留,但您只需添加更多列。我不确定这是否有意义,所以这里是我想要的一个例子 更新!! 保持原来的查询并使用PHP处理结果,也获得了很好的性能。让我知道如果你需要我张贴我的代码。

  • 它重复显示每个房间类型的酒店名称匹配该酒店id,但我想显示所有房间类型的酒店名称一次。我怎样才能做到这一点? 谢谢。

  • 问题内容: 我有一个仅包含2个字段的表。该表具有由这两个字段形成的复合PK。 使用Netbeans从数据库创建实体bean时,不会像其他具有两个以上字段的表那样自动创建实体bean。 所以我想我需要自己创建实体bean。创建此实体bean的最佳实践是什么?是否必须包含对象? 问题答案: 我不使用NetBeans,因此我不能说任何有关其映射工具的信息。 要映射组合键,有两个选项。您可以 用PK字段定

  • 我有一个样本记录如下的数据库设计。问题和答案表共享相同的内容表,存储它们的措辞翻译。通过在内容指示符中指定1,我知道内容的引用是指问题的id(2表示答案)。 问题 回答 内容 我尝试使用以下代码将关系与 JPA 链接起来: 它在编译时抛出以下异常: 由:org.hhibernate引起。MappingException:实体jpatest.model的映射中出现重复列。内容列:引用(应使用inse

  • 问题内容: 我有两个表帐户和余额 我想加入这两个表并获取特定cid的最大日期余额。 输出结果为- 问题答案: 您需要使用两个子查询,如下所示: 输出: 客户编号 姓名 移动的 日期 平衡 1个 美国广播公司 12345 2013年9月20日00:00:00 + 0000 300 2个 XYZ 98475 2013年9月21日00:00:00 + 0000 600 看到这个SQLFiddle

  • 比如说,我有一个名为“Contact”的表,其中“first\u name”和“last\u name”作为列。基本上,“从联系人c中选择concat(c.firstname,,,c.lastname)作为全名”是我在hibernate中想要做的。 我可以将整个查询放在createQuery中,并获得所需的输出。但是,我不想在hibernate中执行sql查询。我在这里找到了一篇类似的帖子“我们可