Spring Boot выбрасывает исключение нулевого указателя при запуске приложения

#spring-boot

#весенняя загрузка

Вопрос:

Я новичок в Spring Boot amp; Hibernate и сталкиваюсь с некоторой ошибкой, в решении которой я прошу помощи. У меня есть 3 объекта, созданные, как показано ниже, с помощью геттеров и сеттеров:

 @Entity
@Table(name="Cinema_Hall")
public class CinemaHall {
    
    @Id
    @Column(name="Hall_Name")
    private String hallName;
    
    @Column(name = "Address_Line_1")
    private String addressLine1;
    
    @Column(name = "Address_Line_2")
    private String addressLine2;
    
    @Column(name = "Address_Line_3")
    private String addressLine3;
    
    @Column(name="No_Of_Screens")
    private int noOfScreens;
    
    @OneToMany(mappedBy="cinemaHall")
    private List<CinemaDetail> runningCinema = new ArrayList<> ();
}

@Entity
@Table(name = "CINEMA_DETAILS")
public class CinemaDetail {

    @Id
    @GeneratedValue
    @Column(name="Cinema_ID")
    private int cinemaID;
    @Column(name="Cinema_Name")
    private String cinemaName;
    @Column(name="Cinema_Begin_Time")
    private String beginTime;
    @Column(name="Cinema_End_Time")
    private String endTime;
    @Column(name="Cinema_Ticket_Price")
    private float ticketPrice;
    @Column(name="Cinema_Screen_No")
    private int screenNo;
    
    @OneToOne
    @JoinColumn(name="Seat_ID", referencedColumnName = "Cinema_ID")
    @Autowired
    private SeatDetail seatDetails;
    
    @ManyToOne
    @JoinColumn(name="Hall_ID", referencedColumnName="Cinema_ID")
    private CinemaHall cinemaHall;
}

@Entity
@Table(name = "Screen_Seats")
public class SeatDetail {
    
    @OneToOne(mappedBy="seatDetails")
    @Id
    @GeneratedValue
    private int ID;
    
    @Column(name = "Seat_No")
    @Convert(converter = SeatDetailConverter.class)
    private List<String> seatNo;
    
    @Column(name = "Seat_Available")
    @Convert(converter = SeatAvailabilityConverter.class)
    private List<Boolean> seatAvailability;
    
    @Transient 
    private final String ALPHABETS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
}
 

Я написал интерфейсы их соответствующих DAO, расширив CrudRepository.
Класс обслуживания такой, как показано ниже:

 @Service
public class CinemaHallRepository {

    private List<CinemaHall> cinemaHalls;
    @Autowired
    private CinemaHallDao cinemaHall;
    
    public CinemaHallRepository() {
        System.out.println("In CinemaHallRepository Constructor");
        addCinemaHall("Roxy", "Roxy Address 1", "Roxy Address 2", "Roxy Address 3", 3);
        addCinemaHall("Hind", "Hind Address 1", "Hind Address 2", "Hind Address 3", 4);
        addCinemaHall("iNox", "INOX Address 1", "INOX Address 2", "INOX Address 3", 5);
        
    }
}
 

Класс контроллера выглядит следующим образом:

 @RestController
public class CinemaHallController {

    @Autowired
    private CinemaHallRepository hallRepository;
        
    @RequestMapping(method=RequestMethod.GET, value=("/cinemahalls"))
    public List<String> getCinemaHalls() {
        //hallRepository.setDefaultCinemaHalls();
        return hallRepository.getCinemaHalls();
}
 

Когда я пытаюсь запустить приложение, на консоли выдается следующая ошибка:

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NullPointerException: Cannot invoke "org.hibernate.mapping.KeyValue.getColumnIterator()" because the return value of "org.hibernate.mapping.PersistentClass.getKey()" is null
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786) ~[spring-beans-5.3.4.jar:5.3.4]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:602) ~[spring-beans-5.3.4.jar:5.3.4]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.4.jar:5.3.4]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.4.jar:5.3.4]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.4.jar:5.3.4]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.4.jar:5.3.4]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.4.jar:5.3.4]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1153) ~[spring-context-5.3.4.jar:5.3.4]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:907) ~[spring-context-5.3.4.jar:5.3.4]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:582) ~[spring-context-5.3.4.jar:5.3.4]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.3.jar:2.4.3]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767) ~[spring-boot-2.4.3.jar:2.4.3]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) ~[spring-boot-2.4.3.jar:2.4.3]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) ~[spring-boot-2.4.3.jar:2.4.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) ~[spring-boot-2.4.3.jar:2.4.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311) ~[spring-boot-2.4.3.jar:2.4.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) ~[spring-boot-2.4.3.jar:2.4.3]
    at com.cinema.hall.ProjectCinemaHallApplication.main(ProjectCinemaHallApplication.java:10) ~[classes/:na]
Caused by: java.lang.NullPointerException: Cannot invoke "org.hibernate.mapping.KeyValue.getColumnIterator()" because the return value of "org.hibernate.mapping.PersistentClass.getKey()" is null
    at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:810) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
    at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:255) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
    at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:101) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processEndOfQueue(InFlightMetadataCollectorImpl.java:1823) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processFkSecondPassesInOrder(InFlightMetadataCollectorImpl.java:1767) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1655) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:295) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1224) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1255) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.3.4.jar:5.3.4]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.3.4.jar:5.3.4]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-5.3.4.jar:5.3.4]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-5.3.4.jar:5.3.4]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.3.4.jar:5.3.4]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1845) ~[spring-beans-5.3.4.jar:5.3.4]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782) ~[spring-beans-5.3.4.jar:5.3.4]
    ... 17 common frames omitted
 

Комментарии:

1. Какую базу данных вы используете?

2. Версия Spring boot?

3. Привет, nurgasemetey, DB — это H2, а версия Spring Boot — 2.4.3

Ответ №1:

@OneToOne(mappedBy = "" ) используется для определения общего ключа. Проблема здесь связана с сопоставлением внешнего ключа и первичного ключа. Когда у вас есть оба @Id и @OneToOne(mappedBy = "") , определенные для одного и того же столбца в следующем классе сущностей, Hibernate не может понять определенное там сопоставление. По всей вероятности, вам придется изменить то, что входит в mappedBy= часть значения.

 @Entity
@Table(name = "Screen_Seats")
public class SeatDetail {
    
    @OneToOne(mappedBy="seatDetails") // you need to remove this and define the mapping in different way
    @Id
    @GeneratedValue
    private int ID;
     ....
}