保存Spring实体

时间:2019-07-14 19:12:56

标签: spring hibernate spring-boot spring-data-jpa

我尝试读取ExcelFiles并将数据保存在postgres数据库中。在某些文件中,我收到以下错误消息:

  

java.lang.NullPointerException:空       在de.hspf.lectureservice.semesterLecture.SemesterLecture.hashCode(SemesterLecture.java:51)〜[classes /:na]       在java.lang.Object.toString(Object.java:236)〜[na:1.8.0_161]       在java.lang.String.valueOf(String.java:2994)〜[na:1.8.0_161]       在java.lang.StringBuilder.append(StringBuilder.java:131)〜[na:1.8.0_161]       在org.hibernate.pretty.MessageHelper.infoString(MessageHelper.java:57)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.NonUniqueObjectException.getMessage(NonUniqueObjectException.java:61)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:123)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:933)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.internal.SessionImpl.merge(SessionImpl.java:892)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.engine.spi.CascadingActions $ 6.cascade(CascadingActions.java:261)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:490)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:415)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:216)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:523)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:455)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:418)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:216)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.engine.internal.Cascade.cascade(Cascade.java:149)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:460)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.event.internal.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:202)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:176)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:69)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:900)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在org.hibernate.internal.SessionImpl.merge(SessionImpl.java:886)〜[hibernate-core-5.3.9.Final.jar:5.3.9.Final]       在sun.reflect.GeneratedMethodAccessor88.invoke(未知来源)〜[na:na]       在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)〜[na:1.8.0_161]       在java.lang.reflect.Method.invoke(Method.java:498)〜[na:1.8.0_161]       在org.springframework.orm.jpa.SharedEntityManagerCreator $ SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:308)〜[spring-orm-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在com.sun.proxy。$ Proxy116.merge(未知来源)〜[na:na]       在org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:492)〜[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]       在sun.reflect.GeneratedMethodAccessor86.invoke(未知来源)〜[na:na]       在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)〜[na:1.8.0_161]       在java.lang.reflect.Method.invoke(Method.java:498)〜[na:1.8.0_161]       在org.springframework.data.repository.core.support.RepositoryComposition $ RepositoryFragments.invoke(RepositoryComposition.java:359)〜[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]       在org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200)〜[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]       在org.springframework.data.repository.core.support.RepositoryFactorySupport $ ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:644)〜[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.data.repository.core.support.RepositoryFactorySupport $ QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:608)〜[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]       在org.springframework.data.repository.core.support.RepositoryFactorySupport $ QueryExecutorMethodInterceptor.lambda $ invoke $ 3(RepositoryFactorySupport.java:595)〜[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]       在org.springframework.data.repository.core.support.RepositoryFactorySupport $ QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)〜[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)〜[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)〜[spring-tx-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)〜[spring-tx-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)〜[spring-tx-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor $ CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:138)〜[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)〜[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)〜[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)〜[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在com.sun.proxy。$ Proxy126.save(未知来源)〜[na:na]       在de.hspf.lectureservice.lecture.LectureService.readExcelFile(LectureService.java:111)〜[classes /:na]       在de.hspf.lectureservice.lecture.LectureService.readExcelFileFolder(LectureService.java:56)〜[classes /:na]       在de.hspf.lectureservice.lecture.LectureService $$ FastClassBySpringCGLIB $$ c90e79de.invoke()〜[classes /:na]       在org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)〜[spring-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.aop.framework.CglibAopProxy $ CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)〜[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)〜[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)〜[spring-tx-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)〜[spring-tx-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)〜[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.aop.framework.CglibAopProxy $ DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)〜[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在de.hspf.lectureservice.lecture.LectureService $$ EnhancerBySpringCGLIB $$ 8c87ac4c.readExcelFileFolder()〜[classes /:na]       在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)〜[na:1.8.0_161]       在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)〜[na:1.8.0_161]       在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)〜[na:1.8.0_161]       在java.lang.reflect.Method.invoke(Method.java:498)〜[na:1.8.0_161]       在org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:261)〜[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:179)〜[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:142)〜[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)〜[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)〜[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)〜[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:402)〜[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:359)〜[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]       在org.springframework.boot.context.event.EventPublishingRunListener.running(EventPublishingRunListener.java:105)〜[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]       在org.springframework.boot.SpringApplicationRunListeners.running(SpringApplicationRunListeners.java:78)〜[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]       在org.springframework.boot.SpringApplication.run(SpringApplication.java:332)上[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]       在org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)上[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]       在org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)上[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]       在de.hspf.lectureservice.LectureServiceApplication.main(LectureServiceApplication.java:15)[classes /:na]

@Entity
public class SemesterLecture implements Serializable {
    @Id
    @ManyToOne
    @JsonIgnore
    @JoinColumn
    private Semester semester;

    @Id
    @ManyToOne
    @JoinColumn
    private Lecture lecture;

    private String grade;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private List<LectureDateTime> lectureDateTimes;

    public SemesterLecture(Lecture lecture, String grade) {
        this.lecture = lecture;
        this.grade = grade;
    }

    public SemesterLecture() {
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof SemesterLecture)) return false;
        SemesterLecture that = (SemesterLecture) o;
        return Objects.equals(semester.getTitle(), that.semester.getTitle()) &&
                Objects.equals(lecture.getTitle(), that.lecture.getTitle());
    }

@Override
    public int hashCode() {
        return Objects.hash(semester.getTitle(), lecture.getTitle(), grade);
    }
@EventListener(ApplicationReadyEvent.class)
    @Transactional
    public void readExcelFileFolder() throws IOException, InvalidFormatException, NotFoundException {
        LOG.info("Load Excel Files from folder...");
        FileFilter filter = new ExcelFileFilter ();
        Resource[] resourceFiles = resourcePatternResolver.getResources("classpath:excel-files/*.xls");
        for (Resource resource : resourceFiles) {
            readExcelFile(resource.getInputStream(), resource.getFilename());
        }
    }

    public void readExcelFile(InputStream inputStream, String fileName) throws IOException, InvalidFormatException, NotFoundException {
        Workbook workbook = WorkbookFactory.create(inputStream);
        DataFormatter dataFormatter = new DataFormatter();
        LOG.info("Read Excel File: " + fileName.substring(0, fileName.lastIndexOf('.')));

        Course existingCourse = courseRepository.findByCourseNumber(fileName.replace(" ", "").substring(0, fileName.lastIndexOf('.')));
        if(existingCourse == null){
            return;
        }
        LOG.info("Found course with title " + existingCourse.getCourseTitle());

        if(existingCourse.getSemesters().size() < 1){
            for(int i = 1; i < 8; i++){
                Semester semester = new Semester();
                semester.setTitle("Semester " + i);
                semester.setSemesterLectures(new ArrayList<SemesterLecture>());
                semester.setSemesterNumber(i);
                existingCourse.getSemesters().add(semesterRepository.save(semester));
            }
            LOG.info("Added " + existingCourse.getSemesters().size() + " Semesters");
        }

        for(int y = 0; y < 5; y++){
            Sheet sheet = workbook.getSheetAt(y);
            for (Row row: sheet) {
                String title = dataFormatter.formatCellValue(row.getCell(0));
                String modulNumber = dataFormatter.formatCellValue(row.getCell(1)).replace(" ", "");
                String language = dataFormatter.formatCellValue(row.getCell(2));
                int semesterNumber = 1;
                try{
                    semesterNumber = Integer.parseInt(dataFormatter.formatCellValue(row.getCell(3)).replace(".", ""));
                }catch (Exception e){}
                if(title instanceof String && modulNumber instanceof String && !title.isEmpty() && !modulNumber.isEmpty() && !title.startsWith("Module")){
                    try{
                        if(lectureRepository.existsByModulNumber(modulNumber.replace(" ", ""))){
                            Lecture lecture = lectureRepository.findByModulNumber(modulNumber.replace(" ", ""));
                            SemesterLecture sm = new SemesterLecture(lecture, "0");
                            sm.setSemester(existingCourse.getSemesters().get(semesterNumber-1));
                            sm.setLecture(lecture);
                            sm.setGrade("0");
                            existingCourse.getSemesters().get(semesterNumber-1).getSemesterLectures().add(sm);
                            LOG.info(sm.getLecture().getTitle() + sm.getSemester().getTitle());
                        }
                    } catch (NumberFormatException e) {
                        throw new NotFoundException("Lecture does not exist");
                    }
                }
            }
        }

        for(Semester semester : existingCourse.getSemesters()){
            semesterRepository.save(semester);
        }
        courseRepository.save(existingCourse);
        LOG.info("Saved all lectures from course " + existingCourse.getCourseTitle());
    }

在大多数已爬网数据中,什么都没有发生。 当我尝试保存semster对象时出现错误。 Excel文件具有以下结构:标题,模块号,语言,学期号

1 个答案:

答案 0 :(得分:1)

跟随堆栈跟踪,我认为您有两个问题:

  • 第一个隐藏在第二个中,这是您要保存一个SemesterLecture实例,该实例的主要ID与已经存在于其中的SemesterLecture实例具有相同的主ID(即,对夫妇SemesterLecture的值相同)数据库,因此可以在堆栈跟踪中看到NonUniqueObjectException
  • 第二个原因是,Spring在尝试打印NonUniqueObjectException的消息时,通过将SemesterLecture类的hash方法调用结束,对于将字段学期或字段演讲设置为null的实例,因此,NullPointerException很好。

我的建议:

首先,删除或注释SemesterLecture类的哈希方法。默认值足以作为开始,它将使您看到原始的异常。我的猜测是,您的学期或Lecture类的hash或equals方法中存在错误,导致休眠状态将两个实体误认为同一实体。