Правильный способ получить результаты от сущностей - PullRequest
0 голосов
/ 22 января 2020

У меня есть два разных небольших проекта в kotlin, один, где работает сопоставление (я не использую класс данных), а другой - где отображение не работает.

Рабочий пример Книга

@Entity
class Book()  {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Int? = null
    var name: String? = null

    @ManyToMany(cascade = [CascadeType.PERSIST, CascadeType.MERGE])
    @JoinTable(name = "BOOK_AUTHOR", joinColumns = [JoinColumn(name = "BOOK_ID", referencedColumnName = "ID")], inverseJoinColumns = [JoinColumn(name = "AUTHOR_ID", referencedColumnName = "ID")])
    private var authors: MutableSet<Author> = HashSet()

//    constructor(name: String?, authors: Set<Author>) : this() {
//        this.name = name
//
//        setAuthors(authors)
//    }

    fun getAuthors(): Set<Author> {
        return authors
    }

    fun setAuthors(authors: Set<Author>) {

        for (author in authors) {
            author.books.add(this)
            this.authors.add(author)
        }
    }
    }

Author

   @Entity
class Author()  {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Int? = null
    var name: String? = null

    @ManyToMany(mappedBy = "authors")
    val books: MutableSet<Book> = HashSet<Book>()


//    constructor(name: String?) : this() {
//        this.name = name
//    }



}

теперь тот, который не работает, с классами данных

Книга

@Entity
data class Book  (
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        val id:Int,
        var name:String,
        @ManyToMany(cascade = [CascadeType.PERSIST, CascadeType.MERGE])
        @JoinTable(name = "BOOK_AUTHOR", joinColumns = [JoinColumn(name = "BOOK_ID", referencedColumnName = "ID")], inverseJoinColumns = [JoinColumn(name = "AUTHOR_ID", referencedColumnName = "ID")])
        private var authors: MutableSet<Author> = HashSet()


){
    constructor() : this(-1,"", mutableSetOf()) {}
//    constructor(name: String) : this() {
//        this.name = name
//        authors = HashSet()
//    }

    constructor(name: String, authors: Set<Author>) : this() {
        this.name = name
        //this.authors = authors;
        setAuthors(authors)
    }

    fun getAuthors(): Set<Author> {
        return authors
    }

    fun setAuthors(authors: Set<Author>) { //this.authors = authors;
//add relations manually
        for (author in authors) {
            author.books.add(this)
            this.authors.add(author)
        }
    }
    override fun toString(): String {
        return "heya"
    }
}

author

@Entity
    data class Author(
            @Id
            @GeneratedValue(strategy = GenerationType.IDENTITY)
            val id:Int,
            var name:String,
            @ManyToMany(mappedBy = "authors")
            val books: MutableSet<Book> = HashSet<Book>()

    ){
        constructor() : this(-1,"", mutableSetOf()) {}
        constructor(name: String) : this() {
            this.name = name
        }

        override fun toString(): String {
            return "heya"
        }
    }

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

Во-вторых, просто ради этого я хотел бы понять, что необходимо для работы отображения класса данных, поскольку теперь он всегда просто выдает ошибку переполнения стека,

1 Ответ

0 голосов
/ 23 января 2020

Согласно JPS spe c, класс сущности должен быть не финальным и должен иметь хотя бы один конструктор без аргументов, а все поля для сохранения должны быть также не финальными.

Итак kotlin класс данных может не работать (но это зависит от того, какую реализацию JPA вы используете). Я бы рекомендовал использовать open class для классов сущностей.

...