0

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.

ahrooran
  • 931
  • 1
  • 10
  • 25

1 Answers1

1

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.

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
  • i know. but i wanted to do a saveall(). isnt a save() will fire multiple queries one for each entity? saveAll() would bulk send all in a single query right. I know that its a transaction amd all but i thought pressure on db would be lower with saveAll(). whats ur opinion on this? – ahrooran Jul 21 '22 at 16:28
  • I think I already answered that in the answer. – Jens Schauder Jul 22 '22 at 06:30
  • https://www.baeldung.com/spring-data-save-saveall – ahrooran Jul 22 '22 at 07:45
  • 1
    Your code is running in a single transaction and you are not generating IDs by the database. Which makes this a very different case then the one used in the article. – Jens Schauder Jul 22 '22 at 07:56