如何使用外键将两个表映射到一个实体?

时间:2012-05-02 16:44:58

标签: java hibernate jpa

我遇到的问题与此非常相似:How do I join tables on non-primary key columns in secondary tables? 但我不确定我是否可以应用相同的解决方案。

我有两张这样的表:

CREATE TABLE CUSTOMER
(
    CUSTOMER_ID INTEGER NOT NULL,
    DETAIL_ID INTEGER NOT NULL,
    PRIMARY KEY( CUSTOMER_ID ),
    CONSTRAINT cust_fk FOREIGN KEY( DETAIL_ID ) REFERENCES DETAILS( DETAIL_ID )
)

CREATE TABLE DETAILS
(
    DETAIL_ID INTEGER NOT NULL,
    OTHER INTEGER NOT NULL,
    PRIMARY KEY( DETAIL_ID )
)

我想将这些表映射到一个名为Customer的类,所以我有:

@Entity
@Table(name = "CUSTOMERS")
@SecondaryTable(name = "DETAILS", pkJoinColumns=@PrimaryKeyJoinColumn(name="DETAIL_ID"))
public class Customer {
    @Id
    @GeneratedValue
    @Column(name = "CUSTOMER_ID")
    private Integer id;

   @Column(table = "DETAILS", name = "OTHER")
   private Integer notes;

   // ...
}

但仅当DETAIL_ID与主表中的CUSTOMER_ID匹配时才有效。

所以我的问题是:如何在主表中使用外键字段来连接辅助表的主键?


更新 我试着设置:

@SecondaryTable(name = "DETAILS", pkJoinColumns=@PrimaryKeyJoinColumn(name="DETAIL_ID", referencedColumnName="DETAIL_ID"))

但是当我运行应用程序时,我得到了这个例外:

org.hibernate.MappingException: Unable to find column with logical name: DETAIL_ID in org.hibernate.mapping.Table(CUSTOMERS) and its related supertables and secondary tables

2 个答案:

答案 0 :(得分:3)

对于任何寻找答案的人来说,使用@SecondaryTable不是连接两个表与非主键列的方法,因为Hibernate默认会尝试通过主键来关联这两个表。你必须使用@OneToMany评论http://viralpatel.net/blogs/hibernate-one-to-many-annotation-tutorial/来获得解决方案,这里是一个代码段,以防网址停止工作:

客户类:

@Entity
@Table(name="CUSTOMERS")
public class Customer {

    @Id
    @GeneratedValue
    @Column(name="CUSTOMER_ID")
    private Integer id;

    @ManyToOne
    @JoinColumn(name="DETAIL_ID")
    private Details details;

    // Getter and Setter methods...
}

详细信息类:

@Entity
@Table(name="DETAILS")
public class Details {

    @Id
    @GeneratedValue
    @Column(name="DETAIL_ID")
    private int detailId;

    @Column(name="OTHER")
    private String other;

    @OneToMany(mappedBy="details")
    private Set<Customer> customers;

    // Getter and Setter methods...
}

使用以下代码可以通过hibernate轻松访问:

Session session = HibernateUtil.getSessionFactory().openSession();
Query query = session.createQuery("select id, details.other from Customer");

我希望这可以帮助那些花费数小时寻找实现这一目标的人,就像我一样。

答案 1 :(得分:0)

您可以使用referenceColumnName注释的@PrimaryKeyJoinColumn属性来定义引用表的连接列。实际上,通过组合使用name / referencedColumnName,您可以在两端都是任意连接,但是如果找到重复项,您的ORM提供程序将抛出异​​常。