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

iecba09b  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(128)

问题是当@ManyToOne生成@联接列ID_REPORT(它是主键)和@联接列ID_TEMPLATE_DEFAULT时
实体Map中的列重复:当前报表列:id_report(应使用insert=“false”update=“false”进行Map)

代码
第一个表格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实体CurReport

@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实体当前报表

@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;

}

当i添加可插入=假,可更新=假时
@联接列(名称=“ID_REPORT”,引用列名=“ID_REPORT”,可插入=假,可更新=假)
所说的
不允许在属性中混合使用可插入列和不可插入列:当前模板
如何Map这些关系?当FK的一个字段是列PK时,如何解析@JoinColumn?

xriantvc

xriantvc1#

您可以使用派生标识并MapCurTemplate,如下所示:

@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
}

然后,您应该使用默认模板键的基本Map,并为默认模板对象提供一个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首先验证新的默认模板是否已经在集合curTemplates中。

相关问题