我正面临一个问题,我正在使用EntityGraph
一次检索所有具有其相关属性的对象,但是Hibernate正在执行查询以解析该图已解决的属性尝试遍历结果时。
____________ _____________________
| invitation | | invitation_response |
|____________| 1 0..1 |____________________ |
| id | ---------- | id |
| event_id | | event_id |
| invitee_id | | invitee_id |
|____________| |_____________________|
@NamedEntityGraph(
name = "graph.Invitation.details",
attributeNodes = [
NamedAttributeNode(value = "response"),
NamedAttributeNode(value = "event", subgraph = "event")
],
subgraphs = [
NamedSubgraph(name = "event", attributeNodes = [
NamedAttributeNode(value = "creator")
]
]
)
class Invitation(
id : Long?,
...
@OneToOne
@JoinColumns(
JoinColumn(name="invitee_id", referencedColumnName = "invitee_id", insertable=false, updatable=false),
JoinColumn(name="event_id", referencedColumnName = "event_id", insertable=false, updatable=false)
)
response: InvitationResponse?,
event: Event
)
class Event(
id: Long?
creator: User
)
所以我有一个graph.Invitation.details
EntityGraph检索:
Invitation
-> Response
-> Creator
interface InvitationRepository : CrudRepository<Invitation, Long> {
@EntityGraph(value = "graph.Invitation.details", type = EntityGraph.EntityGraphType.LOAD)
fun findAllByIdGreaterThan(id: Long, page: Pageable) : Stream<Invitation>
}
当我致电InvitationRepository.findAllByIdGreaterThan
时,最初会看到此查询(为简单起见,汇总视图):
select ...
from invitation invitation0_
left outer join invitation_response invitation_response1_ on invitation0_.invitee_id=invitation_response1_.invitee_id and invitation0_.event_id=invitation_response1_.event_id
left outer join event event2_ on invitation0_.event_id=event2_.id
left outer join user user3_ on event2_.creator_id=user3_.id
where invitation0_.id>?
limit ?
到目前为止,在一个查询中,我正在检索三个实体,但是当我浏览流时,会看到以下内容:
select ...
from invitation_response invitation_response0_
where invitation_response0_.invitee_id=? and invitation_response0_.event_id=?
所以我可以追溯到这种方法:
org.hibernate.engine.internal.TwoPhaseLoad#doInitializeEntity
,在其中调用resolve
方法,这是再次执行查询的代码段:
if ( isReferenceToPrimaryKey() ) {
return resolveIdentifier( (Serializable) value, session );
} else if ( uniqueKeyPropertyName != null ) {
return loadByUniqueKey( getAssociatedEntityName(), uniqueKeyPropertyName, value, session );
}
所以我猜测,由于我的属性没有被其PK引用,因此Hibernate正在重新获取它。所以我的问题是,是否有解决方法?还是Hibernate的错误?
@Query
获得相同结果open class
而不是类来克服Hibernate的限制(默认情况下,Kotlin使类final
,因此将它们声明为open
可以继承它们),如下我读了here @Transactional(readOnly=true)
包围了main方法,因此一切都在同一事务中执行谢谢!