使用外键作为复合键的一部分进行休眠

时间:2015-11-12 21:14:55

标签: java hibernate foreign-keys composite-key

好的,所以我在Oracle数据库上有两个表,我想用Java和Spring 3和Hibernate 3表示它们。它们有多对一的关系,表格就像

 public class Car{
    @Id
    @Column(name="CAR_PK")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,  generator="CAR_KEY_SEQ")
    @SequenceGenerator (name="CAR_KEY_SEQ", sequenceName="CAR_KEY_SEQ", allocationSize=1)
    private long carPk; 

    @OneToMany(cascade= CascadeType.ALL, mappedBy="car")
    @JoinColumn(name="CAR_PK")
    private List<Option> options; 

    //... other stuff
 }

 @IdClass(OptionId.class)
 public class Option{

      @Id
      private long carFk; 

      @Id
      private String optionText; 

      @ManyToOne
      @JoinColumn(name="CAR_FK")
      private Car car; 

      //... other stuff
 }


 @Emeddable
 public class OptionId implements Serializable{

      @Column(CAR_FK)
      private long carFk; 
      @Column(OPTION_TEXT)
      private String optionText
      //... other stuff
 }

因为选项表仅对Car有意义,我们只关心在访问Car时访问它,所以它没有自己独特的PK。此外,每辆车可以有多个选项。因此,我们使用CAR_FK和OPTIONS_TEXT

的复合ID

java就像

 java.sql.SQLException: Invalid column index

在插入时,我希望为Car对象中的carPk生成相同的密钥,以便在Option对象中插入carFk。我该怎么做?我得到了

var rand = new Random();
var num1 = rand.Next(10, 21);

var num2 = rand.Next(50, 61);

var myNum = rand.Next(0, 2) == 1 ? num1 : num2;

我做错了什么?

2 个答案:

答案 0 :(得分:2)

首先,由于Option没有自己的存在,因此它不应该是一个实体。只有Car是一个实体对象而Option是一个值Object,所以它不应该有自己的id。

您可以将设计更改为

 @Entity
 public class Car{
    @Id
    @Column(name="CAR_PK")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,  generator="CAR_KEY_SEQ")
    @SequenceGenerator (name="CAR_KEY_SEQ", sequenceName="CAR_KEY_SEQ", allocationSize=1)
    private long carPk; 

    @Embedded
    private List<Option> options; 

    //... other stuff
 }

@Embeddable
public class Option{
      private String optionText; 

      //... other stuff
 }

这应解决你所有的问题。

答案 1 :(得分:1)

在定义级联类型时,您的上述代码中确实存在拼写错误:

@OneToMany(cascase= CascadeType.ALL, mappedBy="car")

这可能导致您的无效列索引。