Kingshuk Mukherjee
Kingshuk Mukherjee

Reputation: 97

Hibernate mapping with association column from Embeddable

I'm trying to map an entity with an embeddable via a join column available on the embeddable and seems no matter how I do it, it creates an extra map key column in the table for the embeddable.

So here's the entity

@Entity(name = "transaction")
@Table(name = "TRANSACTION_MASTER_V5")
@NoArgsConstructor
@Builder
@Data
@AllArgsConstructor
@DynamicInsert
@DynamicUpdate
public class TransactionMasterV5Entity implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -7817135024822644549L;

    @Id
    @Column(length = 50, name = "TRNSCTN_ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "transactionSeqGen")
    @GenericGenerator(name = "transactionSeqGen", strategy = "com.financemanagement.domaindevelopment.sequencegenerators.newsequences.CommonSequenceGenerator"
            , parameters = {
            @Parameter(name = SequenceStyleGenerator.INCREMENT_PARAM, value = "1"),
            @Parameter(name = CommonSequenceGenerator.VALUE_PREFIX_PARAM, value = "TRN") })
    private String transactionId;

    @Version
    private int version;

    //@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })

    @Column(length = 1000, name = "TRNSCTN_DSCRPTN", nullable = false)
    private String transactionDescription;

    @OneToOne(mappedBy = "parentTransaction", cascade = {CascadeType.MERGE, CascadeType.PERSIST})
    @Fetch(FetchMode.JOIN)
    private TransactionCategoryV5Entity transactionCategory;
    
    @OneToOne(mappedBy = "transactionMasterEntity", cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
    private TransactionLocationV5Entity transactionLocation;

    @Column(name = "TRNSCTN_NTS", columnDefinition = "VARCHAR2(4000)")
    private String transactionNotes;

    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH,
            CascadeType.REMOVE }, fetch = FetchType.EAGER, mappedBy = "parentTransaction")
    private Set<@Valid TransactionItemV5Entity> itemizedTransactions;

    @ElementCollection
    @CollectionTable(name = "ACCOUNT_TRANSACTION_DETAILS_V5",
            joinColumns = @JoinColumn(name = "TRN_ID"
                    , referencedColumnName = "TRNSCTN_ID"))
    @MapKeyClass(TransactionTypeV5Entity.class)
    @Builder.Default
    private Map<TransactionTypeV5Entity, AccountTransactionV5Entity> accountTransactions= new HashMap<>();

}

And here's the embeddable class

@Embeddable
@NoArgsConstructor
@Builder
@Data
@AllArgsConstructor
@DynamicInsert
@DynamicUpdate
public class AccountTransactionV5Entity implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -7817135024822644549L;

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

    @ManyToOne
    @JoinColumn(name = "TRNSCTN_TYP_CD", referencedColumnName = "TRNSCTN_TYP_CD", nullable = false)
    private TransactionTypeV5Entity transactionMethod;

    @ManyToOne
    @JoinColumn(name = "TRNSCTN_CRNCY", referencedColumnName = "CRRNCY_CD", nullable = false)
    @NotNull(message = "Transaction currency must have a value")
    private CurrencyEntity transactionCurrency;

    @Column(name = "TRNSCTN_AMT", columnDefinition = "NUMBER(20,2)")
    @Positive(message = "Transaction amount must be greater than 0.00")
    private BigDecimal transactionAmount;

    @Column(name = "TRNSCTN_DT", columnDefinition = "TIMESTAMP WITH TIME ZONE")
    @Type(type = "org.hibernate.type.OffsetDateTimeType")
    @PastOrPresent(message = "Transaction date must not be a future date")
    private OffsetDateTime transactionDate;

}

So basically what I want is to use the join column TRNSCTN_TYP_CD as the key to Map I have in the entity.

Tried using @MapKey. It throws org.hibernate.AnnotationException: Associated class not found AccountTransactionV5Entity

If I use @MapKeyColumn or @MapClass it creates an additional column which I don't want.

enter image description here

Is there a way around this where I can use the join column TRNSCTN_TYP_CD from the table ACCOUNT_TRANSACTION_DETAILS_V5 as the key to the map?

Appreciate any help I can get on this....!!

Upvotes: 1

Views: 236

Answers (1)

SternK
SternK

Reputation: 13041

I would suggest you to correct your mapping in this way:

@Entity
public class AccountTransactionV5Entity implements Serializable {

    // ...
    
    @ManyToOne
    @JoinColumn(name = "TRNSCTN_TYP_CD", referencedColumnName = "TRNSCTN_TYP_CD", nullable = false)
    private TransactionTypeV5Entity transactionMethod;
}

@Entity
public class TransactionMasterV5Entity implements Serializable {

    // ...

    @OneToMany
    @MapKey(name = "transactionMethod")
    private Map<TransactionTypeV5Entity, AccountTransactionV5Entity> accountTransactions= new HashMap<>();

}

Upvotes: 1

Related Questions