Kotlin Hibernate JPA Lazy提取无法通过控制器工作 [英] Kotlin Hibernate JPA Lazy fetch not working through the controller

查看:166
本文介绍了Kotlin Hibernate JPA Lazy提取无法通过控制器工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里有完整的示例应用程序: https://github.com/MrMojoR/hibernateOnKotlin

I've get a full sample application here: https://github.com/MrMojoR/hibernateOnKotlin

并且此代码基于此博客文章: https://kotlinexpertise.com /hibernate-with-kotlin-spring-boot/

And this code is based on this blogpost: https://kotlinexpertise.com/hibernate-with-kotlin-spring-boot/

问题是,尽管懒惰访存在集成测试中可以正常工作,但调试器中存在异常: 测试异常

The problem is, that while lazy fetch works perfectly from the integration test, there is an Exception in debugger: Exception from test

当我从Controller运行相同的代码时,没有异常,整个实体都被加载: 控制器无异常

When I run the same code from the Controller, there is no Exception, the whole entity is loaded: No Exception from controller

那怎么可能? 非常感谢您的帮助!

How is that possible? Thanks very much for your help!

无论如何,我都会发布代码段:

I'll post the code snippets anyway:

AbstractJpaPersistable.kt

AbstractJpaPersistable.kt

import org.springframework.data.domain.Persistable
import org.springframework.data.util.ProxyUtils
import java.io.Serializable
import javax.persistence.GeneratedValue
import javax.persistence.Id
import javax.persistence.MappedSuperclass
import javax.persistence.Transient

/**
 * Abstract base class for entities. Allows parameterization of id type, chooses auto-generation and implements
 * [equals] and [hashCode] based on that id.
 *
 * This class was inspired by [org.springframework.data.jpa.domain.AbstractPersistable], which is part of the Spring Data project.
 */
@MappedSuperclass
abstract class AbstractJpaPersistable<T : Serializable> : Persistable<T> {

    companion object {
        private val serialVersionUID = -5554308939380869754L
    }

    @Id
    @GeneratedValue
    private var id: T? = null

    override fun getId(): T? {
        return id
    }

    /**
     * Must be [Transient] in order to ensure that no JPA provider complains because of a missing setter.
     *
     * @see org.springframework.data.domain.Persistable.isNew
     */
    @Transient
    override fun isNew() = null == getId()

    override fun toString() = "Entity of type ${this.javaClass.name} with id: $id"

    override fun equals(other: Any?): Boolean {
        other ?: return false

        if (this === other) return true

        if (javaClass != ProxyUtils.getUserClass(other)) return false

        other as AbstractJpaPersistable<*>

        return if (null == this.getId()) false else this.getId() == other.getId()
    }

    override fun hashCode(): Int {
        return 31
    }
}

Person.kt:

Person.kt:

import javax.persistence.CascadeType
import javax.persistence.Entity
import javax.persistence.FetchType
import javax.persistence.ManyToOne
import javax.persistence.OneToMany    

@Entity
class Person(
        val name: String,
        @ManyToOne(cascade = [(CascadeType.ALL)], fetch = FetchType.EAGER)
        val street: Street
) : AbstractJpaPersistable<Long>()

@Entity
class Address(
        val zipCode: String,
        val city: String
) : AbstractJpaPersistable<Long>()

@Entity
class Street(
        @OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.LAZY)
        val adresses: MutableSet<Address>
) : AbstractJpaPersistable<Long>()

PersonRepository:

PersonRepository:

import com.kotlinexpertise.hibernatedemo.model.Person
import org.springframework.data.jpa.repository.JpaRepository

interface PersonRepository : JpaRepository<Person, Long>

PersonService:

PersonService:

import com.kotlinexpertise.hibernatedemo.model.Person
import com.kotlinexpertise.hibernatedemo.repository.PersonRepository
import org.springframework.stereotype.Service

@Service
class PersonService(val personRepository: PersonRepository) {

    fun savePerson(person: Person) {
        personRepository.saveAndFlush(person)
    }
}

解决方案:

这是什么Spring Boot中的spring.jpa.open-in-view = true属性?

此属性应设置为false:

This property should be set to false:

spring.jpa.open-in-view=false

这不是Kotlin问题,而是Spring问题.

It is not a Kotlin issue, but a Spring issue.

推荐答案

懒惰依赖于它具有可用的活动连接这一事实.

Lazy relies on the fact that it has active connection available.

连接由Hibernate中的EntityManager管理.

Connections are managed by EntityManager in Hibernate.

但是您的调试器在完全不同的线程上运行,因此它无法访问EntityManager.因此,例外.

But your debugger runs on a totally different thread, so it doesn't have access to EntityManager. Hence the exception.

这篇关于Kotlin Hibernate JPA Lazy提取无法通过控制器工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆