gpt4 book ai didi

hibernate - Kotlin Hibernate OneToOne fetchtype.LAZY 立即运行所有查询

转载 作者:行者123 更新时间:2023-12-03 11:24:05 24 4
gpt4 key购买 nike

我正在接受培训,培训师使用 Java,我使用的是 Kotlin。到目前为止,我们在任何地方都得到了相同的结果,但在这里我无法让它发挥作用。

有2个实体类:

@Entity
data class Student(
@Id
@GeneratedValue
var id: Long = 0,

@Column(nullable = false)
var name: String = "",

@OneToOne()
var passport: Passport? = null
)

@Entity
data class Passport(
@Id
@GeneratedValue
var id: Long = 0,

@Column(nullable = false)
var number: String = ""
)

在测试类中,我使用实体管理器进行查询。
@RunWith(SpringRunner::class)
@SpringBootTest
class StudentRepositoryTest {
val logger = LoggerFactory.getLogger(this.javaClass)

@Autowired
lateinit var studentRepository: StudentRepository

@Autowired
lateinit var entityManager: EntityManager

@Test
fun retrieveStudentAndPasswordDetails() {
val student: Student? = entityManager.find(Student::class.java, 20001L)

logger.info("Student -> $student")
logger.info("Passport -> `${student?.passport}")
}
}

当我以这种方式运行测试时,输出符合预期
Hibernate: 
select
student0_.id as id1_3_0_,
student0_.name as name2_3_0_,
student0_.passport_id as passport3_3_0_,
passport1_.id as id1_1_1_,
passport1_.number as number2_1_1_
from
student student0_
left outer join
passport passport1_
on student0_.passport_id=passport1_.id
where
student0_.id=?
2017-12-29 20:51:04.258 TRACE 17233 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [20001]
2017-12-29 20:51:04.263 TRACE 17233 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_1_1_] : [BIGINT]) - [40001]
2017-12-29 20:51:04.265 TRACE 17233 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([name2_3_0_] : [VARCHAR]) - [Ranga]
2017-12-29 20:51:04.266 TRACE 17233 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([passport3_3_0_] : [BIGINT]) - [40001]
2017-12-29 20:51:04.267 TRACE 17233 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([number2_1_1_] : [VARCHAR]) - [E123456]
2017-12-29 20:51:04.269 INFO 17233 --- [ main] i.StatisticalLoggingSessionEventListener : Session Metrics {
19949 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
1097216 nanoseconds spent preparing 1 JDBC statements;
227119 nanoseconds spent executing 1 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
}
2017-12-29 20:51:04.269 INFO 17233 --- [ main] c.i.j.h.j.r.StudentRepositoryTest : Student -> Student(id=20001, name=Ranga, passport=Passport(id=40001, number=E123456))
2017-12-29 20:51:04.269 INFO 17233 --- [ main] c.i.j.h.j.r.StudentRepositoryTest : Passport -> `Passport(id=40001, number=E123456)

这看起来真的很好。使用连接调用查询,并显示两个日志输出。

使用 FetchType.LAZY
在这里,我将 FetchType.LAZY 添加到 OneToOne 注释中,这将使护照数据的检索等待到实际需要为止。
@Entity
data class Student(
@Id
@GeneratedValue
var id: Long = 0,

@Column(nullable = false)
var name: String = "",

@OneToOne(fetch = FetchType.LAZY)
var passport: Passport? = null
)

这是我看到一些意外行为的地方。

我希望看到检索学生数据的查询,然后记录学生数据的输出。下一个查询以检索护照数据,最后是护照数据的日志。

当延迟加载会被完全忽略时,我希望仍然可以看到连接,但是有 2 个单独的查询,这似乎比没有延迟加载更糟。
Hibernate: 
select
student0_.id as id1_3_0_,
student0_.name as name2_3_0_,
student0_.passport_id as passport3_3_0_
from
student student0_
where
student0_.id=?
2017-12-29 21:03:53.401 TRACE 17380 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [20001]
2017-12-29 21:03:53.411 TRACE 17380 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([name2_3_0_] : [VARCHAR]) - [Ranga]
2017-12-29 21:03:53.412 TRACE 17380 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([passport3_3_0_] : [BIGINT]) - [40001]
Hibernate:
select
passport0_.id as id1_1_0_,
passport0_.number as number2_1_0_
from
passport passport0_
where
passport0_.id=?
2017-12-29 21:03:53.413 TRACE 17380 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [40001]
2017-12-29 21:03:53.415 TRACE 17380 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([number2_1_0_] : [VARCHAR]) - [E123456]
2017-12-29 21:03:53.427 INFO 17380 --- [ main] i.StatisticalLoggingSessionEventListener : Session Metrics {
33422 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
569626 nanoseconds spent preparing 2 JDBC statements;
1612599 nanoseconds spent executing 2 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
}
2017-12-29 21:03:53.427 INFO 17380 --- [ main] c.i.j.h.j.r.StudentRepositoryTest : Student -> Student(id=20001, name=Ranga, passport=Passport(id=40001, number=E123456))
2017-12-29 21:03:53.427 INFO 17380 --- [ main] c.i.j.h.j.r.StudentRepositoryTest : Passport -> `Passport(id=40001, number=E123456)

@Transactional 注解

其他事情:当培训师在测试方法上运行没有 @Transacional 的测试时,会抛出异常。
就我而言,我是否使用此注释都没有区别。

最佳答案

我今天遇到了这个问题,经过大量研究和测试(Hibernate 编译时检测),我找到的解决方案是:

  • 添加 optional = false到我的 OneToOne
  • 添加 @LazyToOne(LazyToOneOption.PROXY)到我的属性
  • 制作子类 open以及 child 的所有属性 open

  • 在这些步骤之后, hibernate 停止自动获取。

    关于hibernate - Kotlin Hibernate OneToOne fetchtype.LAZY 立即运行所有查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48027924/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com