Hibernate ManyToMany Map <String, Entity>, where the map key is the property referenced by FK

I am working on a complex display of many, many that I want to represent in my essence as a map. The catch is that I want the map key to be a column from one of the related tables, and not a column from the mapping table, as is usually the case.

An account contains basic user information, AccountMetadata defines all the possible attributes that accounts can have, and Account_MetadataAccount defines specific account values ​​for each possible account.

I matched them to the following objects:

@Entity @Table(name = "ACCOUNT") public class Account implements Serializable { @Id @Column(name = "ACCOUNT_ID") private Long accountId; @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "pk.account") private Set<AccountMetadataAccount> metadata = new HashSet<AccountMetadataAccount>(); ... } @Entity @Table(name = "ACCOUNT_METADATA") public class AccountMetadata implements Serializable { @Id @Column(name = "ACCOUNT_METADATA_ID") private Long accountMetadataId; @Column(name = "KEY", unique = true) private String key; @Column(name = "TYPE") private Class<?> type; ... } @Entity @Table(name = "ACCOUNT_METADATA_ACCOUNT") @AssociationOverrides({ @AssociationOverride(name = "pk.account", joinColumns = @JoinColumn(name = "ACCOUNT_ID")), @AssociationOverride(name = "pk.metadata", joinColumns = @JoinColumn(name = "ACCOUNT_METADATA_ID")) }) public class AccountMetadataAccount implements Serializable { @EmbeddedId private AccountMetadataAccountId pk; @Column(name = "VALUE") private Serializable value; ... } @Embeddable public class AccountMetadataAccountId implements Serializable { @ManyToOne private AccountInfo account; @ManyToOne private AccountMetadataInfo metadata; ... } 

All of this works great. My problem is the set of account metadata. This is not perfect. If I have a metadata key, I want to find the value, I have to iterate over the whole set until I find the correct record. There would be hundreds of them in our system. I thought Map<String, AccountMetadataAccount> or Map<String, Serializable> would be more ideal. However, I would like the card key to be the AccountMetadata key.

I experimented with @MapKeyColumn and @MapKeyJoinColumn with no luck. I can find examples where the map key is derived from a column in the connection table.

I hope someone out there has done something similar, or at least has a few words of wisdom on how to do this.

Thanks!

+4
source share
1 answer

How about using getter and setter instead of a member variable? Like this:

 @Transient private Map<String, AccountMetadataAccount> metadata = new HashMap<>(); @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "pk.account") private Collection<AccountMetadataAccount> getMetadata() { return metadata.values(); } private void setMetadata(Collection<AccountMetadataAccount> metaSet) { metadata.clear(); for (AccountMetadataAccount meta : metaSet) { metadata.put(meta.key, meta); } } 

I use xml mapping files instead of annotations, and I still haven’t tested the code, so it may not be 100% correct, but you have to catch the idea.

0
source

Source: https://habr.com/ru/post/1440409/


All Articles