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

时间:2014-01-13 05:31:29

标签: hibernate

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

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

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

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

根据我的表结构,关系表有一个额外的列年份。 我通过定义三个实体程序,preriod_types,program_period_types和关系发送来进行编码

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,year作为主键或不作为主键。

我可以获得任何建议以及正确的代码示例。 我使用注释完成了它。

2 个答案:

答案 0 :(得分:0)

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

首先,您不需要ProgramProgramPeriodType

之间的关系

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

class Program {
    @Id
    String code;

    @OneToMay
    List<ProgramPeriodYear> years;
}

class ProgramPeriodType {
    @Id
    String code;
}

class ProgramPeriodYear {
    @ManyToOne
    Program program;

    @ManyToOne
    ProgramPeriodType periodType;

    String year;
}

然后,下一个程序可以选择ProgramPeriodYear的ID,简而言之,您只需要一个包含programperiodTypeyear的复合键。

其次,如果您的ProgramPeriodType定义是静态的,您可以考虑将其设为枚举,省略ProgramPeriodType实体的需要,并使periodType成为一个简单的列。

答案 1 :(得分:0)

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 + "]";
    }




}

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