首页 > 解决方案 > JPARepository 未保存到数据库

问题描述

长话短说,但这个周末我不得不重新设计一个应用程序。从 Spring Boot 应用程序到 Spring Batch 应用程序。这个过程始终是一个批处理过程,但我试图制作这个批处理引擎,它变得太复杂了,我不得不停止我正在做的事情。我敢肯定我们都去过那里。无论如何,一切都很好!除了我试图保留原始代码的一段代码。我正在尝试使用 JPARepository 保存方法,但它不起作用!我可以调用 save 方法,我觉得 Repo 被实例化了,因为我没有收到空指针异常。事实上,我没有抛出任何异常。我只是在数据库中没有看到任何东西。而且我知道这段代码有效,因为我在以前的设计中运行过它。无论如何,这是我的课...

数据对象:

@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;
}

主键数据类...

@Data
@Embeddable
public class PayeeListPK implements Serializable {

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

回购类...

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

我的服务类...

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

    @Autowired
    PayeeListRepo payeeListRepo;

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

我有一个 Tasklet 的实现,我从我的批处理步骤中调用它......

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;
    }

在我的批处理配置中......

    @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();
    }

最终,我们的步骤是运行 Tasklet 的实现,我们正在自动装配 OracleService 类,然后调用它,然后调用 Repo 方法。我正在使用 Oracle 服务类方法,我正在调用我的 Autowired Repository 的保存方法,但再次没有发生任何事情!

编辑!!!

我已经找到了另一种方法,那就是使用 EntityManager 并使用 persist 和 flush 方法。下面是我的 Oracle 服务类中的 loadToPayeeListTable 方法...

    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();
    }

标签: javaspringjpajdbc

解决方案


将您的 jpa 存储库更改为

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

推荐阅读