Kotlin & Spring (Data): пользовательские сеттеры - PullRequest
0 голосов
/ 27 октября 2018

В настоящее время я работаю над проектом, использующим Spring Boot, написанным на Kotlin. Следует отметить, что я все еще относительно новичок в Kotlin, пришедший с Java. У меня есть небольшая база данных, состоящая из одной таблицы, которая используется для поиска файлов. В этой базе данных я храню путь к файлу (который для этой цели тестирования просто хранится в ресурсах проекта).

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

@Entity
@Table(name = "NOTE_FILE")
class NoteFile {

    @Id
    @GeneratedValue
    @Column(name = "id")
    var id: Int

    @Column(name = "note")
    @Enumerated(EnumType.STRING)
    var note: Note

    @Column(name = "instrument")
    var instrument: String

    @Column(name = "file_name")
    var fileName: String
        set(fileName) {
            field = fileName

            try {
                file = ClassPathResource(fileName).file
            } catch (ignored: Exception) {
            }
        }

    @Transient
    var file: File? = null
        private set

    constructor(id: Int, instrument: String, note: Note, fileName: String) {
        this.id = id
        this.instrument = instrument
        this.note = note
        this.fileName = fileName
    }

}

Я создал следующий репозиторий для извлечения этого объекта из базы данных:

@Repository
interface NoteFileRepository : CrudRepository<NoteFile, Int>

И следующий сервис:

@Service
class NoteFileService @Autowired constructor(private val noteFileRepository: NoteFileRepository) {

    fun getNoteFile(id: Int): NoteFile? {
        return noteFileRepository.findById(id).orElse(null)
    }

}

Проблема, с которой я сталкиваюсь, заключается в том, что при вызове функции getNoteFile не вызывается ни конструктор, ни установщик созданного объекта NoteFile. В результате этого поле file остается пустым, тогда как я ожидаю, что оно будет содержать значение. Обойти эту проблему можно, установив в поле fileName значение этого поля, но это выглядит странно и может вызвать проблемы:

val noteFile: NoteFile? = noteFileService.getNoteFile(id)
noteFile.fileName = noteFile.fileName

Таким образом, вызывается сеттер, и поле file получает правильное значение. Но это не тот путь, о котором говорилось выше. Причиной здесь может быть то, что с платформой Spring Data необходим конструктор по умолчанию. Я использую необходимые плагины Maven, описанные здесь , чтобы заставить Kotlin и JPA работать вместе для начала.

Есть ли какой-нибудь способ, которым конструктор и / или установщик действительно вызывают, когда объект конструируется средой Spring (Data) / JPA? Или, может быть, мне следует явно вызвать установщик fileName в службе, которая получает объект? Или это лучший способ действий для удаления поля file в целом и простого превращения его в функцию, которая извлекает файл и возвращает его таким образом?

...