简体   繁体   中英

Building a map from another table with a composite primary key

I have the following tables in my DB:

statement:
id | created_date | message

and

statement_configuration
id | name | currency

and

statement_balances
statement_id | statement_configuration_id | balance

Where the statement_balances table has a composite primary key on statement_id and statement_configuration_id .

My Statement entity looks like this:

public class Statement implements Serializable {

  @Id
  private long id;

  @Column
  private String message

  //I'm not sure of which annotations I need here
  @OneToMany
  private Map<Long, StatementBalance> statementBalancesByConfigId;
  ....
}

The StatementBalances entity looks like this:

public class Statement implements Serializable {

  @Id
  private long statmentId;

  @Id
  private long statementConfigurationId;

  @Column
  private long balance;
  ....
}

My goal is to build a Map of type Map<Long, StatementBalances> inside my Statement entity. The map will map the statement_configuration_id to a balance ; allowing me to get all the StatementBalance s that are linked to this Statement (keyed by statement_configuration_id ).

Is it possible to build this map using JPA annotations?

Yes this is possible. An example solution:

@Entity
public class Statement implements Serializable {
    @Id
    private long id;

    private String message;

    @OneToMany(mappedBy = "statementId")
    @MapKey(name = "statementConfigurationId")
    private Map<Long, StatementBalances> statementBalancesByConfigId;
}
@Entity
@Table(name = "statement_configuration")
public class StatementConfiguration implements Serializable {
    @Id
    private long id;

    @OneToMany(mappedBy = "statementConfigurationId")
    private Collection<StatementBalances> statementBalances;

    private String name;
    private String currency;
}

The StatementBalancesId composite primary key class and StatementBalances entity class allow modeling a ternary association by creating of two bidirectional relationships between them:

public class StatementBalancesId implements Serializable {
    long statementId;
    long statementConfigurationId;

    // requires no-arg constructor, equals, hashCode
}
@Entity
@Table(name = "statement_balances")
@IdClass(StatementBalancesId.class)
public class StatementBalances implements Serializable {
    @Id
    @ManyToOne
    @JoinColumn(name="statement_configuration_id")
    private StatementConfiguration statementConfigurationId;

    @Id
    @ManyToOne
    @JoinColumn(name="statement_id")
    private Statement statementId;

    @Column
    private long balance;
}

The database tables created this way are identical as those in the question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM