Geoffrey De Vylder
Geoffrey De Vylder

Reputation: 4153

One To Many referencing an entity mapped with Inheritance mapping leads to insert, then update query

I am using Hibernate / JPA 2.1 for persistence in my project. I try to save a FinancialInstrument, which has an embedded field interestRate, which has several PlanSteps The following mapping is set up:

@Entity
@Table(name = "tbl_financial_instrument")
public class FinancialInstrument {

    @Embedded
    private InterestRate interestRate;

    // ...
}

@Embeddable
public class InterestRate {

    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "ir_id")
    private Set<InterestPaymentPlanStep> interestPaymentPlanSteps = new LinkedHashSet<>();

    // ...
}

The plan steps can be reused by different classes, I use inheritance here (single table type).

@Entity
@DiscriminatorValue("INTEREST_PAYMENT")
public class InterestPaymentPlanStep extends PlanStep {
    // ...
}

@Entity
@Table(name = "tbl_plan_step")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "PLAN_STEP_TYPE", discriminatorType = DiscriminatorType.STRING)
public abstract class PlanStep extends AbstractBaseObject {

    // ...
}

I have filled a Financial Instrument with an InterestRate, containing plan steps. Now I'm trying to persist everything to the database I use this code:

private void persistFinancialInstrument(FinancialInstrument financialInstrument) {

    financialInstrument = financialInstrumentRepository.save(financialInstrument);

    if (financialInstrument.getInterestRate() != null) {
        Set<InterestPaymentPlanStep> interestRatePaymentPlanSteps = financialInstrument.getInterestRate().getInterestPaymentPlanSteps();
        for (PlanStep planStep : interestRatePaymentPlanSteps) {
            planStepRepository.save(planStep);
        }
    }
}

The strange thing now is that when I turn on the logging of my queries I see that it executed 2 queries for persisting the plan steps:

This is the first one, note that it does not contain the ID of the financial instrument while I already would expect it here:

insert into tbl_plan_step (creation_datetime, modification_datetime, amount, anchor_date, cap, cycle, floor, rate_add, rate_value, plan_step_type, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, 'INTEREST_PAYMENT', ?)

And the second one:

update tbl_plan_step set ir_id=? where id=?

I have no clue why the saving is being executed in 2 queries. Can anyone find an explanation for this?

Upvotes: 1

Views: 42

Answers (1)

Redlab
Redlab

Reputation: 3118

This likely is due to PlanStep not having the relation to InterestRate. Make the link bidirectional.

@ManyToOne
private InterestRate interestRate

in PlanStep to perform a single insert.

see hibernate documentation for extensive explanation

Upvotes: 1

Related Questions