Thierry Roy
Thierry Roy

Reputation: 8502

How to map composite key of entity in JPA?

I have the REGION table:

REG {
    id number,
    dateCreation Date
  }

I have a LOCALE table:

LOCALE {
     locale String
  }

I have a REGION_DESCRIPTION table:

REGION_DESCRIPTION {
     locale String,
     regId number,
     description
  } 

REGION_DESCRIPTION has a composite key: locale is a foreign key pointing to the LOCALE table. And regId points to the REGION table.

I would like to map this to my Region java class:

private List<RegionDescription> descriptions;

I tried different approache in JPA. But I cannot get the mapping to work. Any suggestions?

Upvotes: 5

Views: 3254

Answers (3)

Rafik BELDI
Rafik BELDI

Reputation: 4158

This should work:

@Entity
public class Region
{
    @Id
    private Long id;
    @Temporal(TemporalType.DATE)
    private Date dateCreation;

    @OneToMany(mappedBy = "regionDescriptionPK.region")
    private List<RegionDescription> descriptions;
}


@Entity
public class RegionDescription
{
    @EmbeddedId
    private RegionDescriptionPK regionDescriptionPK;    
}

@Embeddable
public class RegionDescriptionPK
{
    @ManyToOne
    @JoinColumn(name = "Region_ID")
    private Region region;

    @ManyToOne
    @JoinColumn(name = "locale")
    private Locale locale;
}

@Entity
public class Locale
{
    @Id
    private String name;
}

Upvotes: 0

siebz0r
siebz0r

Reputation: 20329

This should fill your needs:

@Entity
public class Region
{
    @Id
    private Long id;
    @Temporal(TemporalType.DATE)
    private Date dateCreation;
    @OneToMany(mappedBy = "region")
    @JoinColumn(name = "id", referencedColumnName = "region_id")
    private List<RegionDescription> descriptions;
}

@Entity
public class Locale
{
    @Id
    private String name;
}

@Entity
public class RegionDescription
{
    @EmbeddedId
    private RegionDescriptionPK key;

    @MapsId(value = "regionId")
    @ManyToOne
    @JoinColumns({
        @JoinColumn(name = "region_id", referencedColumnName = "id")
    })
    private Region region;

    @MapsId(value = "localeName")
    @ManyToOne
    @JoinColumns({
        @JoinColumn(name = "locale", referencedColumnName = "name")
    })
    private Locale locale;
}

@Embeddable
public class RegionDescriptionPK
{
    @Column(name = "id")
    private Long regionId;

    @Column(name = "locale")
    private String localeName;
}

As a side note, I've seen that this question is quite old. But it isn't closed somehow. :-)

Upvotes: 2

topchef
topchef

Reputation: 19783

You have a case of a join table (REGION_DESCRIPTION) becoming an entity by carrying its own attributes. I would suggest the following:

  1. define RegionDescription as a complete entity with composite primary key class, see example;

  2. define 2 many-to-one relationships in RegionDescription: RegionDescription to Region and RegionDescription to Locale.

  3. alternatively or in addition define one-to-many relationship in Region to map RegionDescription's the way you specified above.

Upvotes: 2

Related Questions