2017-10-12 95 views
0

这里居住是CampaignEntity.class实体:复合键没有得到相应ID

@Entity 
@Table(name = "campaign") 
public class CampaignEntity implements Serializable { 

    @Id 
    @SequenceGenerator(name = "campaign_id_gen", sequenceName = "campaign_seq", initialValue = 1, allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "campaign_id_gen") 
    private Long id; 

    @OneToMany(cascade = CascadeType.REMOVE, mappedBy = "campaignId", fetch = FetchType.EAGER, targetEntity = CampaignCountry.class) 
    private List<CampaignCountry> countries; 

    @Column(name = "include_countries") 
    private Boolean includeCountries; 

    // getters & setters, toString, hashEquals 
} 

这里是CampaignCountry.class我试图映射:

@Entity 
@Table(name = "campaign_country") 
@IdClass(CampaignCountry.CampaignCountryPK.class) 
public class CampaignCountry { 
    @Id 
    @Column(name="campaign_id") 
    private Long campaignId; 
    @Id 
    @Column(name="country") 
    private String country; 

    public CampaignCountry(String country) { 
     this.country = country; 
    } 

    //getters and setters 

    static class CampaignCountryPK implements Serializable { 

     private Long campaignId; 

     private String country; 

     public CampaignCountryPK() {} 

     public CampaignCountryPK(Long campaignId, String country) { 
      this.campaignId = campaignId; 
      this.country = country; 
     } 

     @Override 
     public boolean equals(Object o) { 
      if (this == o) return true; 
      if (o == null || getClass() != o.getClass()) return false; 

      CampaignCountryPK that = (CampaignCountryPK) o; 

      if (campaignId != null ? !campaignId.equals(that.campaignId) : that.campaignId != null) return false; 
      return country != null ? country.equals(that.country) : that.country == null; 
     } 

     @Override 
     public int hashCode() { 
      int result = campaignId != null ? campaignId.hashCode() : 0; 
      result = 31 * result + (country != null ? country.hashCode() : 0); 
      return result; 
     } 
    } 
} 

问题是当我”请致电repository.saveAndFlush(campaignEntity)。它根据我的需要而不是CampaignId保存国家。它始终为空。

org.springframework.orm.jpa.JpaObjectRetrievalFailureException:无法找到domain.CampaignCountry ID为[email protected];

嵌套的例外是javax.persistence.EntityNotFoundException:无法找到domain.CampaignCountry ID为[email protected]

下面是迁移SQL脚本(如果它有什么关系):

CREATE TABLE campaign_country (
    campaign_id BIGINT    NOT NULL, 
    country  CHARACTER VARYING(2) NOT NULL, 
    PRIMARY KEY (campaign_id, country) 
); 

ALTER TABLE campaign_country 
    ADD CONSTRAINT campaign_to_campaign_country FOREIGN KEY (campaign_id) REFERENCES campaign (id); 

那么这里有什么问题,我该如何使用相应的campaignEntity的id填充campaignId?我确实认为它对@OneToMany注解有一些含义,可能无法正确实施。

+0

尝试使用'@OneToMany(cascade = CascadeType.ALL,mappedBy =“campaignId”,fetch = FetchType.EAGER,targetEntity = CampaignCountry.class)' – juvenislux

+0

实体类看起来很奇怪,你是如何创建的? – Frank

+0

@juvenislux没有帮助。仍为空。 – Amiko

回答

1

如何用@EmbeddedId代替?

@Entity 
public class CampaignCountry implements Serializable { 

    @EmbeddedId 
    private CampaignCountryPK id; 

    @MapsId("campaignId") 
    @ManyToOne 
    @JoinColumn(name = "campaign_id") 
    private CampaignEntity campaignEntity; 
} 

@Embeddable 
public class CampaignCountryPK implements Serializable { 

    @Column(name = "campaign_id") 
    private long campaignId; 
    @Column(name = "country") 
    private String country; 
} 

@Entity 
@Table(name = "campaign_country") 
public class CampaignCountry implements Serializable { 

    @EmbeddedId 
    private CampaignCountryPK id; 

    @MapsId("campaignId") 
    @ManyToOne 
    @JoinColumn(name = "campaign_id") 
    private CampaignEntity campaignEntity; 
} 

然后在CampaignEntity变化映射到:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "campaignEntity", fetch = FetchType.EAGER, targetEntity = CampaignCountry.class) 
private List<CampaignCountry> countries; 

你只需要创建的对象为:

List<CampaignCountry> countryList = new ArrayList<>(); 
CampaignEntity campaign = new CampaignEntity(); 

CampaignCountryPK pk1 = new CampaignCountryPK(); 
pk1.setCountry("Country 1"); 
CampaignCountry country1 = new CampaignCountry(); 
country1.setId(pk1); 
country1.setCampaignEntity(campaign); 

countryList.add(country1); 
campaign.setCountries(countryList); 

或者,您可以创建用于创建PK的方法。

+0

我照你说的去做了。 映射@MapsId时引用实体上的意外标识符类型:com.newagesol.promotion.domain.CampaignEntity – Amiko

+0

是'includeCountries'数据库列?如果不是,你尝试将它标记为'@瞬态' – juvenislux

+0

是的。我刚刚检查过它。 – Amiko