使用带有hibernate的复合键

时间:2013-01-03 01:55:46

标签: java hibernate jpa

假设我想要一个复合键作为购买订单实体的街道,城市。

以下是我如何识别它,

    @Embeddable
    public class BillingAddress implements Serializable {

        private String street;
        private String city;

        public BillingAddress(){

        }

        public BillingAddress(String street, String city) {
            this.street = street;
            this.city = city;
        }
        //with getters and setters
}



@Entity
@IdClass(BillingAddress.class)
public class PurchaseOrder {

    public PurchaseOrder(BillingAddress billingAddress) {
        street = billingAddress.getStreet();
        city = billingAddress.getCity();

    }

    @Id
    @AttributeOverrides({
            @AttributeOverride(name = "street", column = @Column(name = "STREET")),
            @AttributeOverride(name = "city", column = @Column(name = "CITY")) })
    private String street;
    private String city;
    private String itemName;

    public String getItemName() {
        return itemName;
    }

    public void setItemName(String itemName) {
        this.itemName = itemName;
    }

}

我想了解@AttributeOverrides注释到底是做什么的?即使我将colomn名称更改为STREET1,我仍然会看到使用列名称STREET创建的表。那么在这里做什么是column = @Column(name =“STREET”))。

另外,不是使用BillingAddress的constructore,我可以将它像PurchaseOrder类的字段一样,

 public class PurchaseOrder {
     BillingAddress billingAddress;

}

在这种情况下,这将如何改变? 我还需要私人String街吗?私人弦城;在PurchaseOrder?

最后我读到在使用复合主键的新数据库系统设计中应该避免使用复合键,这种情况下为了映射遗留数据库表而不改变数据库表结构对吗?该陈述是否有效?

//编辑问题

保存采购订单中的帐单邮寄地址,

PurchaseOrder purchaseOrder = new PurchaseOrder();
purchaseOrder.setItemName("name");

BillingAddress billingAddress = new BillingAddress();
billingAddress.setCity("c1"); billingAddress.setStreet("s1");                                                              purchaseOrder.setBillingAddress(billingAddress); 
session.save(purchaseOrder);

2 个答案:

答案 0 :(得分:1)

你提出的问题很少,我试图通过所有问题并回答每一个问题:

@AnnotationOverride做什么?

在这里回答:What does @AttributeOverride mean?

第二个问题对我来说有点不清楚,但我想你是否要在PurchaseOrder类中包含复合键的所有字段。

不,我不这么认为。这是我快速拼凑的一个例子:

@Entity
@Table(name = "PURCHASE_ORDER")
public class PurchaseOrder{

    @Id
    private BillingAddress billingAddress;

    //getters & setters

    @Embeddable
    public static class BillingAddress implements Serializable {
        @Column(name = "street")
        private String street;
        @Column(name = "city")
        private String city;
        @Column(name = "itemName")
        private String itemName;

        //getters & setters

    }
}

不要担心语法,只需要担心结构。您甚至可以在PurchaseOrder中添加额外的字段,而不是id。

我应该使用复合键吗?

在这里回答:Should I use composite primary keys or not?

答案 1 :(得分:0)

好吧,您的PurchaseOrder类不会从任何类型的映射实体扩展,并且您(当前)应用@AttributeOverride的属性也不会扩展。因此,实际上没有任何内容可以覆盖,而您的JPA提供程序只是忽略了注释。我认为你要做的是为实体定义一个嵌入式id,同时覆盖该id的一些列映射。您可以对当前代码进行一些修改来完成此操作:

@Entity
public class PurchaseOrder {
    @EmbeddedId
    @AttributeOverrides({
            @AttributeOverride(name = "street", column = @Column(name = "BILLING_STREET")),
            @AttributeOverride(name = "city", column = @Column(name = "BILLING_CITY")) })
    private BillingAddress billingAddress;

    private String itemName;

    // Constructors, Getters/Setters
}

请注意,我已经更改了重写属性的名称,因为对于您当前的示例,嵌入的ID名称和重写的名称是相同的。