Updating a child entity

88 Views Asked by At

This is bit lengthy but a simple conceptual problem. Please take some time to read :)

I have 2 tables with exactly same columns except their primary keys are different. So I have created a @MappedSuperclass with common columns and have child classes annotated with @Entity

@MappedSuperclass
public abstract class AbstractCorporateAction {

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "ticker_serial", nullable = false, insertable = false, updatable = false)
    @ToString.Exclude
    private Ticker ticker;

    @Column(name = "corp_act_type", nullable = false, precision = 4)
    private BigInteger corpActType;

    @Column(name = "number_of_shares", precision = 20)
    private BigInteger numberOfShares;
}

Here are the child classes:

@Entity
@Table(name = "corporate_actions", schema = "dfn_content_data")
public class ContentDataCorporateAction extends AbstractCorporateAction {

    @Id
    @Column(name = "action_id", precision = 10)
    private BigInteger id;
}

@Entity
@Table(name = "corporate_actions", schema = "dfn_ms_history")
public class MsHistoryCorporateAction extends AbstractCorporateAction {

    @Id
    @Column(name = "id")
    private BigInteger id;

    @Column(name = "source_action_id", length = 20, unique = true)
    private String sourceActionId;
}

You can see primary key of one child class is action_id while other is just id. My task is to retrieve rows from both, do some calculation, update corresponding fields and push back.

I did all except the last part which is pushing back to DB. I now have a list of data: List<AbstractCorporateAction> and I want to push back.

  1. I tried creating a DAO by extending extends JpaRepository<AbstractCorporateAction, BigInteger>. But failed because there is no @Id attribute in AbstractCorporateAction

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'abstractCorporateActionDao' defined in com.gtn.ca_adjustments.repository.calculation.AbstractCorporateActionDao defined in @EnableJpaRepositories declared on CalculationPersistenceConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: This class [class com.gtn.ca_adjustments.entity.calculation.AbstractCorporateAction] does not define an IdClass

  2. I then tried to convert this to an inheritance table

    @Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public abstract class AbstractCorporateAction { }

Again failed because there is no common Id.

What can I do at this point?

I have tried:

interface ContentDataCorporateActionDao extends JpaRepository<ContentDataCorporateAction, BigInteger> {

}

interface MsHistoryCorporateActionDao extends JpaRepository<MsHistoryCorporateAction, BigInteger> {

}

@Repository
public class AbstractCorporateActionDao {

    // Autowire both
    private final ContentDataCorporateActionDao contentDataCorporateActionDao;

    private final MsHistoryCorporateActionDao msHistoryCorporateActionDao;

    @Transactional
    public void saveAll(List<AbstractCorporateAction> abstractCorporateActions) {
        
        // 1. filter all actions belong to first child class into a list
        // 2. filter all actions belong to second child class into another list
        
        // 3. for each list -> saveALl() to corresponding dao
        
    }
}

IS this approach the only one? This seems too much for the task.

1

There are 1 best solutions below

4
Jens Schauder On

You can simplify this a little by:

iterate over the list.
    foreach:
        do an instanceof check
        save with the matching repository.

So no need to create the intermediate lists. Since your JPA implementation will delay the updates anyway nothing is gained by using saveAll.