简体   繁体   English

JPARepository 未保存到数据库

[英]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.从 spring boot 应用程序到 spring 批处理应用程序。 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!!我正在尝试使用 JPARepository 保存方法,但它不起作用!! I am able to call the save method, I feel like the Repo is instantiated because I'm not getting a null pointer exception.我可以调用 save 方法,我觉得 Repo 被实例化了,因为我没有收到空指针异常。 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...我有一个 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;
    }

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.最终,我们的步骤是运行 Tasklet 的实现,我们正在自动装配 OracleService 类,然后调用该类,然后调用 Repo 方法。 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!!我正在使用 Oracle 服务类方法,我正在调用我的 Autowired Repository 的 save 方法,但同样什么也没有发生!!

EDIT!!!编辑!!!

I have figured out another way to do it and that is with EntityManager and using the persist and flush methods.我想出了另一种方法,那就是使用 EntityManager 并使用persist 和flush 方法。 Below is now my loadToPayeeListTable method in my Oracle Service class...下面是我的 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();
    }

Could you have a try to passe the repository with a Spring Test?您可以尝试通过 Spring 测试通过存储库吗? I have never met this problem, but I am not sure about the DB type.我从来没有遇到过这个问题,但我不确定数据库类型。 Is it Mysql, Oracle?是 MySQL 还是 Oracle? Because I never used it with @EmbeddedId.因为我从未将它与@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将您的 jpa 存储库更改为

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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