处理程序调度失败;嵌套的异常是java.lang.StackOverflowError

时间:2019-05-04 11:32:27

标签: spring api spring-mvc

我正在创建一个演示春季项目,其中讲师和课程之间存在一对多的双向映射。我创建了一个API来列出讲师和课程。

Instructor.java

@Entity
@Table(name="instructor")
public class Instructor {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private int id;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

    @Column(name="email")
    private String email;

    /*
     * instructor class has @OneToMany relationship with course
     */

    //One instructor can have may course
    @OneToMany(mappedBy="instructor",
               cascade = {  CascadeType.DETACH,
                            CascadeType.MERGE,
                            CascadeType.PERSIST,
                            CascadeType.REFRESH
                         }
               )//it refers to instructor object/property defined in Course.java
    private List<Course> courses;

//getter and setters

Course.java

@Entity
@Table(name="course")
public class Course {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private int id;

    @Column(name="title")
    private String title;

    /*
     * course table has @ManyToOne mapping with Instructor
     */
    @ManyToOne(cascade = {  CascadeType.DETACH,
                            CascadeType.MERGE,
                            CascadeType.PERSIST,
                            CascadeType.REFRESH
                         })

    @JoinColumn(name="instructor_id") //Course column name in instructor_id
    /*
     * instructor_id has a key that point to actual instructor id
     * it's FK and it's relationship is defined in the db
     */
    private Instructor instructor;

//getters and setters   

CommonRestController.java

@RestController
@RequestMapping("/api")
public class CommonRestController {

    //Inject Service
    @Autowired
    private CommonService theCommonService;

        /*
         * For COURSES
         */

        //1. API to get Courses
        @GetMapping("/Course/courses")
        public List<Course> getCourses(){
            return theCommonService.getCourses();
        }

        //---------------------------------------------

        /*
         * For INSTRUCTORS
         */

        //1. API to get Instructors
        @GetMapping("/Inst/instructors")
        public List<Instructor> getInstructors(){
            return theCommonService.getInstructors();
        }
}

服务等级

CommonServiceImpl.java

    //Inject Course DAO
    @Autowired
    private CourseDAO courseDAO;

    //Inject Instructor DAO
    @Autowired
    private InstructorDAO instructorDAO;

    //1. For Courses        

            @Override
            @Transactional
            public List<Course> getCourses() {
                return courseDAO.getCourses();
            }

    //********************************************************************

    //2. For Instructor

            @Override
            @Transactional
            public List<Instructor> getInstructors(){
                return instructorDAO.getInstructors();
            }

}

DAO类

InstructorDAO类

    //Inject Session Factory
    @Autowired
    private SessionFactory theSessionFactory;

    @Override
    public List<Instructor> getInstructors() {

        //1. Start the Hibernate Session
        Session theSession = theSessionFactory.getCurrentSession();

        //2. Create the Instructor.... sort by last_name
        Query<Instructor> theQuery = theSession.createQuery("from Instructor order by lastName",Instructor.class);

        //3. Execute the query, get the resulted list
        List<Instructor> tempInstructor = theQuery.getResultList();

        /*
         * For checking purpose
         */

        for(int i=0 ; i<tempInstructor.size();i++) {
            System.out.println(tempInstructor.get(i));
        }

        //4. Return the result
        return tempInstructor;
    }
}


CourseDAO类

    //Inject SessionFactory
    @Autowired
    private SessionFactory theSessionFactory;

    @Override
    public List<Course> getCourses() {

        // 1. Get Current Hibernate Session
        Session theSession = theSessionFactory.getCurrentSession();

        // 2. Create Query... order courses by title
        Query<Course> theQuery = theSession.createQuery
                                ("from Course order by title",Course.class);

        // 3. Execute the query and get the result
        List<Course> tempCourse = theQuery.getResultList();

        /*
         * Show Courses
         */
        for(int i=0; i<tempCourse.size();i++) {
            System.out.println(tempCourse.get(i));
        }

        // 4. Return the result
        return tempCourse;
    }


下面是配置Java类

DemoAppConfig.java

@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan("com.luv2code.springdemo")
@PropertySource({ "classpath:persistence-mysql.properties" })
public class DemoAppConfig implements WebMvcConfigurer {

    @Autowired
    private Environment env;

    private Logger logger = Logger.getLogger(getClass().getName());

    // define a bean for ViewResolver

    @Bean
    public DataSource myDataSource() {

        // create connection pool
        ComboPooledDataSource myDataSource = new ComboPooledDataSource();

        // set the jdbc driver
        try {
            myDataSource.setDriverClass("com.mysql.jdbc.Driver");       
        }
        catch (PropertyVetoException exc) {
            throw new RuntimeException(exc);
        }

        // for sanity's sake, let's log url and user ... just to make sure we are reading the data
        logger.info("jdbc.url=" + env.getProperty("jdbc.url"));
        logger.info("jdbc.user=" + env.getProperty("jdbc.user"));

        // set database connection props
        myDataSource.setJdbcUrl(env.getProperty("jdbc.url"));
        myDataSource.setUser(env.getProperty("jdbc.user"));
        myDataSource.setPassword(env.getProperty("jdbc.password"));

        // set connection pool props
        myDataSource.setInitialPoolSize(getIntProperty("connection.pool.initialPoolSize"));
        myDataSource.setMinPoolSize(getIntProperty("connection.pool.minPoolSize"));
        myDataSource.setMaxPoolSize(getIntProperty("connection.pool.maxPoolSize"));     
        myDataSource.setMaxIdleTime(getIntProperty("connection.pool.maxIdleTime"));

        return myDataSource;
    }

    private Properties getHibernateProperties() {

        // set hibernate properties
        Properties props = new Properties();

        props.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
        props.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql"));

        return props;               
    }


    // need a helper method 
    // read environment property and convert to int

    private int getIntProperty(String propName) {

        String propVal = env.getProperty(propName);

        // now convert to int
        int intPropVal = Integer.parseInt(propVal);

        return intPropVal;
    }   

    @Bean
    public LocalSessionFactoryBean sessionFactory(){

        // create session factorys
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();

        // set the properties
        sessionFactory.setDataSource(myDataSource());
        sessionFactory.setPackagesToScan(env.getProperty("hibernate.packagesToScan"));
        sessionFactory.setHibernateProperties(getHibernateProperties());

        return sessionFactory;
    }

    @Bean
    @Autowired
    public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {

        // setup transaction manager based on session factory
        HibernateTransactionManager txManager = new HibernateTransactionManager();
        txManager.setSessionFactory(sessionFactory);

        return txManager;
    }   

}


MySpringMvcDispatcherServletInitializer.java

public class MySpringMvcDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { DemoAppConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

}


期望的结果是获得讲师和课程的详细信息,而不是得到

“处理程序调度失败;嵌套异常为java.lang.StackOverflowError”

该如何解决?

0 个答案:

没有答案