我正在进行培训,培训师正在使用Java,而我正在使用Kotlin。到目前为止,我们到处都有相同的结果,但在这里我无法让它发挥作用。
有两个实体类:
@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
)
这是我看到一些意外行为的地方。
我期望看到查询检索学生数据,然后记录学生数据的输出。下一个查询检索护照数据,最后是护照数据的日志。
当延迟加载完全被忽略后,我本来期望仍然看到连接,但是有两个单独的查询,这似乎使事情更糟,然后没有延迟加载。
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)
其他内容:当培训师在测试方法上运行没有@Transacional
的测试时,会抛出异常。
就我而言,我是否使用此注释没有任何区别。
答案 0 :(得分:0)
我今天遇到了这个问题,经过大量的研究和测试(Hibernate编译时工具),我找到的解决方案是:
optional = false
添加到我的OneToOne
@LazyToOne(LazyToOneOption.PROXY)
添加到我的属性open
,并将子类的所有属性也open
这些步骤之后,休眠状态将自动停止获取。