2012-03-26 200 views
1

首先,我对Hibernate有点新。要了解我在一个项目中使用它的技术。我试图映射以下数据库:休眠数据库映射

Campaign 
    campaignId(+) 
    name 

Promotion 
    campaignId(+) 
    discount(+) 
    product 
    message 

我已经在(+)两种情况下指出了主键。 Promotion中的'campaignId'是Campaign建立1:m映射模型的外键(一个Campaign有许多促销活动)。使用注释我坚持如何做到这一点。

我真的不想在Promotion表中添加promotionId,因为它使得数据繁琐。这当然会使桥接表有点棘手。我也遇到了使用也是主键一部分的外键的问题。

是否可以完成这一映射?


好的,我得到了它的工作。有点。必须检查持久性是否真的有效。我做了以下内容:

@Entity 
@Table(name = "CAMPAIGNS") 
@Audited 
public class CampaignEntity { 
    private int campaignId; 
    private String name; 
    private List<PromotionEntity> promotions; 

    public CampaignEntity(int campaignId, String name) { 
     this.campaignId = campaignId; 
     this.name = name; 
    } 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "cmp_id") 
    public int getCampaignId() { 
     return campaignId; 
    } 

    public void setCampaignId(int campaignId) { 
     this.campaignId = campaignId; 
    } 

    // Campaign name here... left out to save space 

    @OneToMany 
    @JoinColumn(name = "cmp_id") 
    public List<PromotionEntity> getPromotions() { 
     return promotions; 
    } 

    public void setPromotions(List<PromotionEntity> promotions) { 
     this.promotions = promotions; 
    } 
} 

推广是香草映射(不使用后,所有的嵌入式),与字段:CAMPAIGNID,折扣,消息。 (它也没有@ManyToOne批注。)

这有道理吗?

最后,这将是一等奖:你可以看到我正在使用Envers审计整个事情。上面创建了一个相当丑陋的“CampaignEntity_PromotionEntity_AUD”表。我知道这是必要的,但我怎样才能将它重命名为CAMPAIGN_PROMOTION_AUD?

谢谢你们!


我得到了一个孤独的网站深深地隐藏在Hibernate的吉拉错误跟踪网站的远角落的答案:https://hibernate.onjira.com/browse/HHH-3729

答案当然是使用@AuditJoinTable(name =“CAMPAIGN_PROMOTION_AUD”)。

+0

您的意思是您可能不希望在* Campaign *表格中使用promotionId?我不确定这是否合理。 – 2012-03-26 14:05:02

+0

更正后,广告系列ID应作为单个列(cmp_id)存储在促销表中,该列也是促销主键的一部分。 (见上)。我想我已经与上面编辑的解决方案,谢谢你的帮助。 – 2012-03-26 16:46:46

回答

0

这就是我现在使用的。它运作良好,Hibernate为我处理促销活动的PK。再次感谢。

@Entity 
@Table(name = "CAMPAIGNS") 
@Audited 
public class CampaignEntity { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", nullable = false) 
    private Integer campaignId; 

    @Column(name = "name", nullable = false, unique = true) 
    private String campaignName; 

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) 
    @JoinTable(name = "CAMPAIGN_PROMOTIONS", 
       joinColumns = { @JoinColumn(name = "campaign_id") }, 
       inverseJoinColumns = { @JoinColumn(name = "promotion_id") }) 
    private Set<PromotionEntity> promotions; 

    ... 
} 

然后,PromotionEntity:

@Entity 
@Table(name = "PROMOTIONS") 
@Audited 
public class PromotionEntity implements Comparable<PromotionEntity> { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Integer id; 

    @Column(name = "discount", nullable = false) 
    private Integer discount; 

    @Column(name = "message", nullable = false) 
    private String message; 

    ... 
} 

我也喜欢注释字段,而不是干将,因为它是更紧凑,更易于读取。

1

这是一对多关系及其相反的基本示例。

public class Campaign 
{ 
    @OneToMany(mappedBy = "campaign) 
    private List<Promotion> promotions; 
} 

public class Promotion 
{ 
    @ManyToOne 
    private Campaign campaign; 
} 
+0

这不太合适......“广告系列广告系列”条目很难将其定义为促销主键的一部分。我需要“campaign_id”作为此表中的外键,同时也是Promotion主键的一部分。 “活动ID”与“折扣”一起定义了该实体的唯一性。 – 2012-03-26 16:10:43

+1

它为什么需要成为主键的一部分?只需使用非业务PK(即“id”字段)并将您的业务密钥定义为(唯一)索引。 – 2012-03-27 10:44:33

+0

当广告系列从前端更新后,我会收到一个包含一组促销(包含折扣,产品和消息)的广告系列。我现在必须编写查询来查找所有促销活动的PK,只需更新活动即可。 (请记住,我没有从集合中获得PK。)这听起来很不对。 – 2012-03-27 13:53:29

1

您可以使用EmbeddedId创建一个多字段PK。

  • Promotion
  • 卸下PK字段创建一个单独的实体,说PromotionPK外,不@Column对PK字段的任何注解
  • Promotion,包括PK类作为字段,使用@EmbeddedId注释它,用吸气剂和吸气剂

FK映射如Wouter所示。

+0

你介意举个简单的例子吗?我不知道如何使用这个组合键来映射@ManyToOne注解......这是哪里去的?在组合键或Promotion类中? – 2012-03-26 16:11:45

+0

我已经整理过了......感谢您的帮忙。 – 2012-03-26 17:31:42