Почему спящий режим не удается сохранить? - PullRequest
1 голос
/ 14 апреля 2020

Я использую Flyway, чтобы попытаться создать, а затем заполнить базу данных при запуске веб-приложения Spring Boot. Flyway успешно создает таблицы базы данных при первой миграции, но не заполняет их во 2-й из-за исключения NullPointerException.

Вот код миграции, называемый V2_seed_database. java, расположенный в пакете db.migration:

package db.migration;

import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;

import net.tekknow.medaverter.db.seeds.AppointmentSeeder;

public class V2__seed_database extends BaseJavaMigration {
    public void migrate(Context context) {
        AppointmentSeeder appointmentSeeder = new AppointmentSeeder();
        appointmentSeeder.seed();
    }
}

Вот код AppointmentSeeder:

package net.tekknow.medaverter.db.seeds;

import org.json.JSONArray; 
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import net.tekknow.medaverter.domain.Appointment;
import net.tekknow.medaverter.service.AppointmentService;

@Service
public class AppointmentSeeder {
    @Autowired
    AppointmentService appointmentService;

    @PostConstruct
    public void seed() {
        String json = "[" +
            "{\"id\":1,\"patient_id\":1,\"dateTime\":\"10/29/2010\",\"physician_id\":1,\"lab_id\":1,\"note_id\":0}" +
        "]";
        org.json.JSONArray appointments = new JSONArray(json);

        for (int i=0; i<appointments.length(); i++) {
            JSONObject appointment = appointments.getJSONObject(i);
            Appointment dbAppointment = new Appointment();
            dbAppointment.setId(appointment.getInt("id"));
            dbAppointment.setPatientId(appointment.getInt("patient_id"));
            dbAppointment.setDateTime(appointment.getString("dateTime"));
            dbAppointment.setPhysicianId(appointment.getInt("physician_id"));
            dbAppointment.setLabId(appointment.getInt("lab_id"));
            dbAppointment.setNoteId(appointment.getInt("note_id"));
            appointmentService.save(dbAppointment);
        }
    }
}   

Вот код AppointmentRepository:

package net.tekknow.medaverter.db;

import org.springframework.data.jpa.repository.JpaRepository;
import net.tekknow.medaverter.domain.Appointment;

public interface AppointmentRepository extends JpaRepository<Appointment,Integer> {
}

А вот код AppointmentService:

package net.tekknow.medaverter.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import net.tekknow.medaverter.db.AppointmentRepository;
import net.tekknow.medaverter.domain.Appointment;

@Service
@Transactional
public class AppointmentService {

    @Autowired
    AppointmentRepository repo;

    public void save(Appointment appointment) {
        System.out.println("AppointmentService.save: appointment="+appointment.toString());
        repo.save(appointment);  //its failing here
    }  
}

Вот компонент назначения:

package net.tekknow.medaverter.domain;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

@Entity
@Table(name = "appointments")
public class Appointment {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @NotBlank
    @Column(unique = true)
    private int patient_id;
    @Size(max = 32)
    private String date_time;
    private int physician_id;
    private int lab_id;
    private int note_id;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
... other getters and setters, truncated for brevity

Когда я запускаю программу, миграция запускается, но в этой строке происходит сбой:

    repo.save(appointment);  //its failing here

со следующим сообщением об ошибке:

Причина: java .lang.NullPointerException: null at net .tekknow.medaverter.service.AppointmentService.save (AppointmentService. java: 32) ~ [классы /: на ]

Непосредственно перед неудачной строкой кода я выводю содержимое объекта, который, по его словам, имеет значение null и не равно null:

AppointmentService.save: Встреча = ID: 1, Patient_id: 1, date_time: 29.10.2010, doctor_id: 1, lab_id: 1, note_id: 0

Есть предложения?

Ответы [ 3 ]

1 голос
/ 14 апреля 2020

Это не связано с режимом гибернации, вы используете инъекцию пружинных зависимостей неправильно: вы пытаетесь автоматически связать поля c, что недопустимо.

См. Можете ли вы использовать @ Автоматическое подключение с полями stati c? .

Обновление

Теперь у вас есть

AppointmentService appointmentService = new AppointmentService();

вместо введения этого поля в Сеялка.

Seeder должен быть bean-компонентом, управляемым Spring (вероятно, @Service), если вы хотите, чтобы внедрение зависимостей работало. См. Также @PostConstruct, вы можете использовать его для вызова метода после инициализации bean-компонента.

Обновление 2

Вы по-прежнему сами создаете экземпляры Spring bean с помощью new, и, следовательно, не вводить ваши зависимости.

AppointmentSeeder appointmentSeeder = new AppointmentSeeder();

Однако вы успешно продвинули проблему на один шаг к Flyway. Теперь проблема заключается в том, что миграция Flyway не является бобами Spring: они создаются Flyway, а не Spring, и поэтому Spring не имеет своих автоматических связей.

Flyway 4.1 решил эту проблему, позволив использовать предварительно Spring-бины (или другие Java объекты) с небольшим количеством настроек

См. API: Позволяет использовать предварительно созданные Java -перемещенные миграции # 1062 .

ApplicationContext applicationContext = ...; // obtain a reference to Spring's ApplicationContext.

Flyway flyway = Flyway.configure()
    .dataSource(url, user, password)
    // Add all Spring-instantiated JavaMigration beans
    .javaMigrations(applicationContext.getBeansOfType(JavaMigration.class).values().toArray(new JavaMigration[0]))
    .load();
flyway.migrate();

см. Также JavaMigration и BaseJavaMigration javado c.

0 голосов
/ 15 апреля 2020

сделать это в AppointmentSeeder,

@Autowire
AppointmentService service;

public void seed() {
        String json = "[" +
            "{\"id\":1,\"patient_id\":1,\"dateTime\":\"10/29/2010\",\"physician_id\":1,\"lab_id\":1,\"note_id\":0}" +
        "]";
        org.json.JSONArray appointments = new JSONArray(json);

        for (int i=0; i<appointments.length(); i++) {
            JSONObject appointment = appointments.getJSONObject(i);
            Appointment dbAppointment = new Appointment();
            dbAppointment.setId(appointment.getInt("id"));
            dbAppointment.setPatientId(appointment.getInt("patient_id"));
            dbAppointment.setDateTime(appointment.getString("dateTime"));
            dbAppointment.setPhysicianId(appointment.getInt("physician_id"));
            dbAppointment.setLabId(appointment.getInt("lab_id"));
            dbAppointment.setNoteId(appointment.getInt("note_id"));
            service.save(dbAppointment);
        }
    }
0 голосов
/ 14 апреля 2020

возможно, вам следует изменить значение ** note_id ** в вашем файле JSON на 1 !

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...