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

Hibernate中的困难与使用没有复合键的注释的额外列的多对多关系

缪晋
2023-03-14

我尝试了与表结构的多对多关系

Programs
---------
Program_cd,
Program_name

period_types
-------------
period_type_cd,
Period_type

Program_period_years
---------------------
Program_cd,
Period_type_cd,
year

根据我的表结构,关系表有一个额外的列year。我通过定义三个实体程序、preriod\u类型、program\u period\u类型和关系来进行编码

one to many between program and program_period_types
one to many between period_types and program_period_types
many to one between program_period_types and programs
many to one between program_period_types and period types

现在的问题是,根据代码,(Program_cd,Period_type_cd)充当复合键,我不想让Program_cd、Period_type_cd、年份这三列作为主键或不作为主键。

我可以得到任何建议以及适当的代码示例吗?我已经使用注释完成了。

共有2个答案

范翰飞
2023-03-14
the relationships defined are correct

one to many between program and program_period_types
one to many between period_types and program_period_types
many to one between program_period_types and programs
many to one between program_period_types and period types

i dont know how to make three column(program_cd,period_type_cd and year) as composite key in the relation table as year is an extra column
can some one guide me with my code


-------------------------------------------------------------------------------------------
Code as  follows:

-------------------------------------------------------------------------------------------

DROP TABLE IF EXISTS `test`.`programs`;
CREATE TABLE  `test`.`programs` (
  `program_cd` varchar(45) NOT NULL,
  `program_name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`program_cd`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


DROP TABLE IF EXISTS `test`.`period_types`;
CREATE TABLE  `test`.`period_types` (
  `period_type_cd` varchar(45) NOT NULL,
  `period_type` varchar(45) NOT NULL,
  PRIMARY KEY (`period_type_cd`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


DROP TABLE IF EXISTS `test`.`periods_for_program_and_year`;
CREATE TABLE  `test`.`periods_for_program_and_year` (
  `program_cd` varchar(45) NOT NULL,
  `year` varchar(45) NOT NULL,
  `period_type_cd` varchar(45) NOT NULL,
  PRIMARY KEY (`program_cd`,`year`,`period_type_cd`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


-------------------------------------------------------------------------------------------

Entity Clasess:

-------------------------------------------------------------------------------------------

Entity class for program table
--------------------------------------------------------------------------------------

package test;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

@Entity  
@Table(name = "programs")  
public class Program_Years implements java.io.Serializable{

    private static final long serialVersionUID = 1L;

    String program_cd;
    String program_name;
    private Set<Periods_for_program_and_year> periods_for_program_and_year = new HashSet<Periods_for_program_and_year>(0);

    public Program_Years() {
        // TODO Auto-generated constructor stub
    }

    public Program_Years(String program_cd, String program_name) {
        super();
        this.program_cd = program_cd;
        this.program_name = program_name;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.programcd", cascade=CascadeType.ALL)
    public Set<Periods_for_program_and_year> getPeriods_for_program_and_year() {
        return periods_for_program_and_year;
    }

    public void setPeriods_for_program_and_year(
            Set<Periods_for_program_and_year> periods_for_program_and_year) {
        this.periods_for_program_and_year = periods_for_program_and_year;
    }

    @Id
    @Column(name = "program_cd" ,unique = true, nullable = false) 
    public String getProgram_cd() {
        return program_cd;
    }
    public void setProgram_cd(String program_cd) {
        this.program_cd = program_cd;
    }

    @Column(name = "program_name", nullable = false, length = 20) 
    public String getProgram_name() {
        return program_name;
    }
    public void setProgram_name(String program_name) {
        this.program_name = program_name;
    }

    @Override
    public String toString() {
        return "Program_Years [program_cd=" + program_cd + ", program_name="
                + program_name + "]";
    }




}

-----------------------------------------------------

Entity class for period types table
----------------------------------------------------------------------------------------

package test;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity  
@Table(name = "Period_Types") 
public class Period_Types implements java.io.Serializable{

    private static final long serialVersionUID = 1L;

    String period_type_cd;

    String period_type;

    private Set<Periods_for_program_and_year> periods_for_program_and_year = new HashSet<Periods_for_program_and_year>(0);

public Period_Types() {
    // TODO Auto-generated constructor stub
}

    public Period_Types(String period_type_cd, String period_type) {
        super();
        this.period_type_cd = period_type_cd;
        this.period_type = period_type;
    }

    @Id
    @Column(name = "period_type_cd",unique = true, nullable = false) 
    public String getPeriod_type_cd() {
        return period_type_cd;
    }

    public void setPeriod_type_cd(String period_type_cd) {
        this.period_type_cd = period_type_cd;
    }

    @Column(name = "period_type", nullable = false, length = 10, unique = true)
    public String getPeriod_type() {
        return period_type;
    }

    public void setPeriod_type(String period_type) {
        this.period_type = period_type;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.periodtypecd")
    public Set<Periods_for_program_and_year> getPeriods_for_program_and_year() {
        return periods_for_program_and_year;
    }

    public void setPeriods_for_program_and_year(
            Set<Periods_for_program_and_year> periods_for_program_and_year) {
        this.periods_for_program_and_year = periods_for_program_and_year;
    }

    @Override
    public String toString() {
        return "Period_Types [period_type_cd=" + period_type_cd
                + ", period_type=" + period_type + "]";
    }




}
-----------------------------------------------------------------------------------

Entity class for relational table
------------------------------------------------------------------------------------

package test;


import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

@Entity
@Table(name = "periods_for_program_and_year")
@AssociationOverrides({
        @AssociationOverride(name = "pk.programcd", 
            joinColumns = @JoinColumn(name = "program_cd")),
        @AssociationOverride(name = "pk.periodtypecd", 
            joinColumns = @JoinColumn(name = "period_type_cd")) })
public class Periods_for_program_and_year implements java.io.Serializable{

    private static final long serialVersionUID = 4050660680047579957L;

    private Periods_for_program_and_yearID pk = new Periods_for_program_and_yearID();
    private String year;


    @EmbeddedId
    public Periods_for_program_and_yearID getPk() {
        return pk;
    }
    public void setPk(Periods_for_program_and_yearID pk) {
        this.pk = pk;
    }

    @Transient
    public Program_Years getProgramcd() {
        return getPk().getProgramcd();
    }

    public void setProgramcd(Program_Years c) {
        getPk().setProgramcd(c);
    }


    @Transient
    public Period_Types getPeriodtypecd() {
        return getPk().getPeriodtypecd();
    }

    public void setPeriodtypecd(Period_Types c) {
        getPk().setPeriodtypecd(c);
    }


    @Column(name = "year", nullable = false, length = 10)
    public String getYear() {
        return year;
    }
    public void setYear(String year) {
        this.year = year;
    }


    @Override
    public int hashCode() {
        return (getPk() != null ? getPk().hashCode() : 0);
    }



    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof Periods_for_program_and_year))
            return false;
        Periods_for_program_and_year other = (Periods_for_program_and_year) obj;
        if (pk == null) {
            if (other.pk != null)
                return false;
        } else if (!pk.equals(other.pk))
            return false;
        if (year == null) {
            if (other.year != null)
                return false;
        } else if (!year.equals(other.year))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Periods_for_program_and_year [pk=" + pk + ", year=" + year
                + "]";
    }





}
------------------------------------------------------------------------------------
Entity class whhich acts as a composite key

--------------------------------------------------------------------------------------

package test;

import javax.persistence.Embeddable;
import javax.persistence.ManyToOne;

@Embeddable
public class Periods_for_program_and_yearID implements java.io.Serializable{

    private static final long serialVersionUID = -9120607274421816301L;
    private Program_Years programcd;
    private Period_Types periodtypecd;

    @ManyToOne
    public Program_Years getProgramcd() {
        return programcd;
    }
    public void setProgramcd(Program_Years programcd) {
        this.programcd = programcd;
    }

    @ManyToOne
    public Period_Types getPeriodtypecd() {
        return periodtypecd;
    }
    public void setPeriodtypecd(Period_Types periodtypecd) {
        this.periodtypecd = periodtypecd;
    }

    @Override
    public int hashCode() {
         int result;
            result = (programcd != null ? programcd.hashCode() : 0);
            result = 17 * result + (periodtypecd != null ? periodtypecd.hashCode() : 0);
            return result;
    }


    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof Periods_for_program_and_yearID))
            return false;
        Periods_for_program_and_yearID other = (Periods_for_program_and_yearID) obj;
        if (periodtypecd == null) {
            if (other.periodtypecd != null)
                return false;
        } else if (!periodtypecd.equals(other.periodtypecd))
            return false;
        if (programcd == null) {
            if (other.programcd != null)
                return false;
        } else if (!programcd.equals(other.programcd))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "Periods_for_program_and_yearID [programcd=" + programcd
                + ", periodtypecd=" + periodtypecd + "]";
    }




}

-----------------------------------------------------------------
乐城
2023-03-14

首先,有些关系似乎不必要,有些东西可能会简化您的设计。

首先,您不需要程序和程序周期类型之间的关系

根据您的设计,您真正需要的是:

class Program {
    @Id
    String code;

    @OneToMay
    List<ProgramPeriodYear> years;
}

class ProgramPeriodType {
    @Id
    String code;
}

class ProgramPeriodYear {
    @ManyToOne
    Program program;

    @ManyToOne
    ProgramPeriodType periodType;

    String year;
}

然后下一个程序是选择的ID,简而言之,您可以简单地拥有一个包含ProgramperiodType的复合键年

其次,如果您的ProgramPeriodType定义相当静态,您可以考虑将其设置为枚举,这样就省去了对ProgramPeriodType实体的需要,并将其设置为一个简单的列。

 类似资料:
  • 我正在hibernate的帮助下开发一个电子购物程序。因为我是jsp、servlet、hibernate的新手,我不知道如何使用关系表中的附加列进行多对多关系映射。我已经阅读了几篇教程,但其中大部分都是关于hibernate社区的注释映射和文档,但没有一篇适合我的情况。 我有三个表,分别是电影信息表、订单详情表和订单详情表(关系表),其中订单详情表的结构如下所示。 我正在尝试使用四个POJO类来实

  • 您好,我有多对多映射,在联接表中有额外的列。表结构如下所示。 关系如下 链接 我创建了如下POJO类 Vendor.java 学生。爪哇 测试。爪哇 供应商est.java 供应商学生测试PK。爪哇 Hibernate映射文件,如下所示 vendor.hbm.xml vendor\u student\u测试。hbm。xml 大学生hbm。xml 测验hbm。xml 我刚开始Hibernate,这是

  • 我用复合键定义了两个实体之间的多对多关系。问题是,当我获得join对象时,它只被过滤了关系的一侧,而不是两边。 图片使问题更加清晰。这里,我要查找的是dtid=185和prid=352,但我从多对多关系中得到的是两个突出显示的行。 天丁:

  • 我想使用XML映射在Hibernate中映射多对多的关系。 我有两个类,和。我想创建一个链接表女巫将包含复合键和3个额外的列

  • 我有域类 - 用户、角色、组、组角色 用户域 用户.hbm.xml 我有user_grouprole表作为一个连接表为一个用户和一组分组程序我有user_role表作为一个连接表为一个用户和一组角色 组域 Group.hbm.xml 组角色 GroupRole.hbm.xml 当我尝试使用主类进行测试时,我得到了一个映射错误,比如Hibernate映射错误,比如外键(FK5110401A83989

  • 我在拉雷维尔的这种多对多关系中过得很艰难。我有一个多对多的关系,项目和人。我还有第三个表roles(有两列:id、name),其中包含一个人在项目中可以扮演的角色(在本例中为“actor”、“director”等)。透视表person\u project有“person\u id”、“project\u id”和“role\u id”列。我成功地让所有与项目相关的人员使用 但是我怎么能让人在项目中