我正在接受培训,培训师使用 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/