休眠查询再次由EntityGraph

时间:2018-07-09 17:34:24

标签: java hibernate spring-boot spring-data entitygraph

我正面临一个问题,我正在使用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的错误?

一些其他信息:

  • 无法修改表结构
  • 堆栈:JDK8,Spring boot 2.0.0.RC2,Hibernate 5.2
  • 已尝试使用@Query获得相同结果
  • 在创建代理时已经尝试使用open class而不是类来克服Hibernate的限制(默认情况下,Kotlin使类final,因此将它们声明为open可以继承它们),如下我读了here
  • @Transactional(readOnly=true)包围了main方法,因此一切都在同一事务中执行

谢谢!

0 个答案:

没有答案