简体   繁体   中英

JPARepository is not saving to DB

Long story, but I had to redesign an application this weekend. From a spring boot app to a spring batch app. The process was always a batch process, but I tried to make this batch engine and it got way too complex and i had to stop what I was doing. I'm sure we've all been there. Anyway everything is working fine!! Except for one piece of code that I tried to keep the original piece of code for. I'm trying to use a JPARepository save method and it's not working!! I am able to call the save method, I feel like the Repo is instantiated because I'm not getting a null pointer exception. In fact, I'm not getting any exceptions thrown. I am just not seeing anything in the DB. And I know this code has worked because I had it running in the previous design. Anyway here are my classes...

Data object:

@Data
@Entity
@Table(name="PAYEE_QUAL_LS")
public class PayeeList {

    @EmbeddedId
    private PayeeListPK payeeListPK = new PayeeListPK();
    @Column(name = "PAYEE_QUAL_CD")
    private String payeeQualCode;
    @Column(name = "ETL_TS")
    private Timestamp etlTimestamp;
}

Primary key data class...

@Data
@Embeddable
public class PayeeListPK implements Serializable {

    @Column(name = "PAYEE_NM")
    private String payeeName;
    @Column(name = "BAT_PROC_DT")
    private Date batchProcDate;
}

Repo class...

@Repository
public interface PayeeListRepo extends JpaRepository<PayeeList,String> {}

My Service class...

public class OracleService {
    private static final Logger logger = LoggerFactory.getLogger(OracleService.class);

    @Autowired
    PayeeListRepo payeeListRepo;

    public void loadToPayeeListTable(PayeeList payeeList) {
        payeeListRepo.save(payeeList);
    }

I have an implementation of Tasklet which I am calling from my batch Step...

public class PayeeListTableLoad implements Tasklet {
    private static final Logger logger = LoggerFactory.getLogger(PayeeListTableLoad.class);

    private java.sql.Date procDt;
    private String inputFile;
    private Timestamp time;
    private int safeRecordCount = 0;
    private int blockRecordCount = 0;
    private int safeRejectRecordCount = 0;
    private int blockRejectRecordCount = 0;
    private ArrayList<String> rejectRecordList = new ArrayList<>();

    @Autowired
    OracleService oracleService;

    @Override
    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        java.util.Date parsed = format.parse(System.getenv("procDt"));
        procDt = new java.sql.Date(parsed.getTime());
        inputFile = Constants.filePath;
        time = new Timestamp(System.currentTimeMillis());

        logger.info("Running data quality checks on input file and loading to Oracle");

        try (BufferedReader reader = new BufferedReader(new FileReader(inputFile))) {
            String line = reader.readLine();
            while (line != null) {
                if (dataQuality(line)) {
                    PayeeList payeeList = buildPayeeListObject(line);
                    oracleService.loadToPayeeListTable(payeeList);
                    logger.info("Record loaded: " + line);
                } else {
                    rejectRecordList.add(line);
                    try {
                        if (line.split("\\|")[1].equals("B")) {
                            blockRejectRecordCount++;
                        } else if (line.split("\\|")[1].equals("S")) {
                            safeRejectRecordCount++;
                        }
                        logger.info("Record rejected: " + line);
                    } catch (ArrayIndexOutOfBoundsException e) {
                        e.printStackTrace();
                    }
                }
                line = reader.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        logger.info("Safe record count is: " + safeRecordCount);
        logger.info("Block record count is: " + blockRecordCount);
        logger.info("Rejected records are: " + rejectRecordList);

        SendEmail sendEmail = new SendEmail();
        sendEmail.sendEmail(Constants.aegisCheckInclearingRecipient,Constants.aegisCheckInclearingSender,Constants.payeeListFileSuccessEmailSubject,Constants.payeeListFileSuccessEmailBodyBuilder(safeRecordCount,blockRecordCount,safeRejectRecordCount,blockRejectRecordCount,rejectRecordList));

        logger.info("Successfully loaded to Oracle and sent out Email to stakeholders");

        return null;
    }

In my batch configuration....

    @Bean
    public OracleService oracleService() { return new OracleService(); }

    @Bean
    public PayeeListTableLoad payeeListTableLoad() {
        return new PayeeListTableLoad();
    }

    @Bean
    public Step payeeListLoadStep() {
        return stepBuilderFactory.get("payeeListLoadStep")
                .tasklet(payeeListTableLoad())
                .build();
    }

    @Bean
    public Job loadPositivePayFile(NotificationListener listener, Step positivePayLoadStep) {
        return jobBuilderFactory.get("loadPositivePayFile")
                .incrementer(new RunIdIncrementer())
                .listener(listener)
                .start(positivePayDataQualityStep())
                .next(initialCleanUpStep())
                .next(positivePayLoadStep)
                .next(metadataTableLoadStep())
                .next(cleanUpGOSStep())
                .build();
    }

Ultimately our step is running an implementation of Tasklet, we are Autowiring out OracleService class, and then that is being called and is then calling the Repo method. I am getting to the Oracle Service class method and I am calling the save method of my Autowired Repository but again nothing is happening!!

EDIT!!!

I have figured out another way to do it and that is with EntityManager and using the persist and flush methods. Below is now my loadToPayeeListTable method in my Oracle Service class...

    public void loadToPayeeListTable(PayeeList payeeList) throws ParseException {
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        entityManager.persist(payeeList);
        entityManager.flush();
        transaction.commit();
        entityManager.close();
    }

Could you have a try to passe the repository with a Spring Test? I have never met this problem, but I am not sure about the DB type. Is it Mysql, Oracle? Because I never used it with @EmbeddedId. IF you passed the unit test, you ought to check your service logic with debugging. Opposite, you ought to passe the test first.

Change your jpa repository to

@Repository
public interface PayeeListRepo extends JpaRepository<PayeeList, PayeeListPK>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM