У меня есть приложение Spring, где я храню некоторые настройки приложения в базе данных (например, почтовый хост, имя пользователя и т. Д. c.). Я использую стандартный подход, как и всегда - у меня есть Entity, Service и Repository.
Я использую сервис настроек в моем JavaMailSenderImpl
для получения конфигурации электронной почты из БД:
@Configuration
public class EmailConfig {
private static final String SETTING_NAME_EMAIL_HOST = "MAIL_HOST";
private SettingsService settingsService;
@Bean
public JavaMailSenderImpl mailSender() {
// Ommited rest of the method
JavaMailSenderImpl emailSender = new JavaMailSenderImpl();
String host = settingsService.getByName(SETTING_NAME_EMAIL_HOST).getValue();
emailSender.setHost(host);
return emailSender;
}
Такой подход хорошо работает, когда я запускаю приложение. Но когда я пытаюсь запустить свои тесты JUnit, все они проваливаются при запуске. Я получаю исключение NullPointerException:
Failed to instantiate [org.springframework.mail.javamail.JavaMailSenderImpl]: Factory method 'mailSender' threw exception; nested exception is java.lang.NullPointerException
в строке ниже:
String host = settingsService.getByName(SETTING_NAME_EMAIL_HOST).getValue();
Я потратил некоторое время, пытаясь это исправить, и обнаружил, что служба возвращает ноль, даже если такая данные фактически существуют в базе данных. Что интересно, settingsRepository.findByName(SETTING_NAME_EMAIL_HOST);
возвращает ноль, но settingsRepository.getOne(1);
возвращает действительные объекты.
Мои вопросы:
Почему findBy*
возвращает ноль, а getOne()
метод работает хорошо?
Есть ли обходной путь для моей проблемы в моих тестах? Может быть, как-нибудь издеваетесь над почтовой службой?
Ниже моего кода:
Настройки сущности
@Entity
@Table(name = "settings")
public class Setting {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "name", unique = true)
@NotEmpty(message = "{setting.name.empty}")
private String name;
@Column(name = "description")
private String description;
@Column(name = "example")
private String example;
@Column(name = "value")
@NotEmpty(message = "{setting.name.empty}")
private String value;
}
Настройки службы
@Service
public class SettingsService {
private SettingsRepository settingsRepository;
@Autowired
public void setSettingsRepository(SettingsRepository settingsRepository) {
this.settingsRepository = settingsRepository;
}
public Setting getByName(String name) {
return settingsRepository.findByName(name);
}
// other methods
}
Настройки хранилища
@Repository
public interface SettingsRepository extends JpaRepository<Setting, Integer> {
Setting findByName(String name);
}