8

我有两个模型。

@Entity
public class Student
{
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    protected long id;

    @?
    protected Address homeAddress;

    @?
    protected Address schoolAddress;
}

@Entity
public class Address
{
   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   protected long id;

   @?
   protected List<Student> students;
}

我需要在上面放置哪些 JPA/hibernate 注释homeAddressschoolAddress并使students关联工作?

当然,我尝试了很多东西,但没有任何效果。例如,设置

    @ManyToOne
    @JoinColumn (name="student_homeAddress_id", updatable = false, insertable = false)
    protected Address homeAddress;

    @ManyToOne
    @JoinColumn (name="student_schoolAddress_id", updatable = false, insertable = false)
    protected Address schoolAddress;

    @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER)
    @JoinColumns({
    @JoinColumn(name = "student_homeAddress_id", referencedColumnName = "student_homeAddress_id"),
    @JoinColumn(name = "student_schoolAddress_id", referencedColumnName = "student_schoolAddress_id")})
    @IndexColumn(name="students_index")
    protected List<Student> students;

Unable to find column with logical name: student_homeAddress_id in org.hibernate.mapping.Table(Address) and its related supertables and secondary tables。也尝试过使用mappedBy,但这需要一个参数(不能做mappedBy="student_homeAddress_id, student_schoolAddress_id".

还考虑将其JoinColumns移至Student平板电脑,但我不确定 OneToMany 和 ManyToOne 的注释应该是什么样子,因为我在那里有多个地址,而 JoinColumns 没有多大意义。

确实有效但没有创建关联的事情是:

    @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER)
    @JoinColumn(name="address_id")
    @IndexColumn(name="students_index")
    protected List<Student> students;

使用这个,当在数据库中存储模型时,student_homeAddress_id 和 student_schoolAddress_id 始终为空,即使在存储了两端(学生和地址模型)之后也是如此。

我的想法是在Address桌子上会有3个额外的列:student_homeAddress_id(学生表中学生的家庭地址的id),student_schoolAddress_id(学生表中学生的id)和students_index(0 -基于students列表中的位置)。这应该足够了,对吗?

有任何想法吗?

非常感谢!

4

2 回答 2

6

我们尝试了 mael 的建议,但无法实现。

我们最终遵循了这个有效的方法。

换句话说,我们有OneToMany关系:

Student

protected List<AddressStudentAssociation> addresses;

Address

protected List<AddressStudentAssociation> students;

并且在AddressStudentAssociation

@ManyToOne
@PrimaryKeyJoinColumn(name="STUDENTID", referencedColumnName="id")
private Student student;
@ManyToOne
@PrimaryKeyJoinColumn(name="ADDRESSID", referencedColumnName="id")
private Address address;

加上一个将一个地址与另一个地址分开的参数 ( isHome)。

最后,在里面Student我们public Address getHomeAddress()遍历addresses列表并返回正确的地址。我们还必须使用注释才能使其正常工作。一般来说不是最优的,但它可以工作,我们已经花了太多时间试图让事情正常进行。:|

于 2012-10-31T14:06:00.027 回答
4

如果您有一个要在多个字段中关联 @OneToMany 的实体,您应该使用 @JoinTable 以便 Hibernate 可以为该关系生成 2 个表。

来自@JoinTable javadoc:

连接表通常用于多对多和单向一对多关联的映射。它还可用于映射双向多对一/一对多关联、单向多对一关系和一对一关联(双向和单向)。

当连接表用于映射关系与关系拥有方的可嵌入类时,包含实体而不是可嵌入类被认为是关系的所有者。

如果缺少 JoinTable 注释,则应用注释元素的默认值。连接表的名称假定为使用下划线连接在一起(拥有方优先)的关联主表的表名。

举个例子:

@Entity
@Indexed(index = "causa_penal")
@Table(name = "causas_penales")
public class CausaPenal implements Serializable {



     @Id
     @GeneratedValue(strategy = GenerationType.TABLE)
     @Column(name = "id")
     @DocumentId
     private Integer id;

     @Version
     @Column(name = "opt_lock")
     private Integer version;

     @ManyToMany(cascade = { CascadeType.ALL })
     @JoinTable(name = "causapenal_imputados")
     @IndexedEmbedded(depth = 1)
     private List<ParteMaterial> imputados;

     @ManyToMany(cascade = CascadeType.ALL)
     @JoinTable(name = "causapenal_victimas")
     @IndexedEmbedded(depth = 1)
     private List<ParteMaterial> victimas;

    //Getters and Setters
}

如您所见,我让 CausaPenal 两次指向 ParteMaterial。但我需要这些列表彼此独立。因此,使用@JoinTable 我告诉 Hibernate 这种关系必须映射到 4 个表:“causa_penal”用于 CausaPenal 实体,“causa_penal_imputados”用于 CausaPenal 和映射到 ParteMaterial 实体的 imputados 字段的关系,对于受害者和相同最后,ParteMaterial 实体表。

于 2012-10-12T14:39:47.813 回答