当目标有复合键时@OneToMany关系?

时间:2012-06-26 13:02:04

标签: jpa eclipselink

嗨我想为我的一个项目建立一对多的关系,但从不填充List。

我有一个父源类

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class ParentJob {
  @Id
  @Column(name = "ID")
  int id;
}

一个孩子

@Entity
public class TakeJob extends ParentJob {
  @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.REMOVE)
  @JoinColumn(name="FK_JOBID", referencedColumnName="ID")
  private List<JobRelation> jobRelations;
}

和目标实体

@Entity
public class JobRelation {
  @EmbeddedId
  private JobRelationPK JobRelationPK;
}

用PK

@Embeddable
public class JobRelationPK implements Serializable {
  private long fkSomething;
  @Column(name = "FK_JOBID")
  private long fkJobId;
}

现在正如我所说,如果我访问它,List就不会填充。我对JoinColumn的语法特别感兴趣,因为即使它是完全垃圾,我为'name'设置的内容并不重要。我必须注意我放在那里的东西,或者我可以把'name =“COLUMN_NAME_IN_JOBRELATION”'

编辑:我正在使用EclipseLink 2.3.2

2 个答案:

答案 0 :(得分:3)

这里的问题可能在于您希望如何设置JobRelation表的“FK_JOBID”字段。

映射的方式使其可以通过嵌入的JobRelationPK的fkJobId属性和TakeJob的jobRelations映射进行写入。如果您只在JobRelation实体中设置它,那么TakeJob集合将仅在刷新时反映更改 - JPA要求您维护关系以使它们与数据库中的内容保持一致。这意味着您仍然必须将JobRelation添加到TakeJob的集合中,以便引用与数据库中的内容同步,或者在提交更改后刷新它。

但是因为你有两个映射到这个字段,所以需要将join列设置为只读以避免写入问题。

更好的解决方案可能是在JobRelation上为TakeJob设置ManyToOne关系,然后将TakeJob的jobRelations映射设置为由这个新映射(而不是使用joincolumn)映射。如果使用JPA 2.0,则可以将新映射指定为@MapsId(“fkJobId”)。类似的东西:

@Entity public class JobRelation {
   @EmbeddedId
   private JobRelationPK JobRelationPK;
   @ManyToOne
   @MapsId("fkJobId")
   private TakeJob job;
 } 

这将允许嵌入的fkJobId属性在插入时使用引用的TakeJob Id中的值进行设置。

答案 1 :(得分:1)

首先应该将注释放在实体层次结构中的位置保持一致。总是将它们放在田地上,或者总是把它们放在吸气剂上。您的getter上的注释将被忽略,因为@Id注释放在id字段上。

修复此问题后,name中的@JoinColumn必须是加入列的名称....所以它必须是JobRelation表中列的名称,它是TakeJob表的外键。