JPA Entity Subgraph, включенный в запрос, но все еще ищет отдельную сущность - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть система, которая загружает данные из файлов в реляционную базу данных, чтобы проверить целостность отношений, чтобы идентифицировать и удалить отношения без родителя. У меня есть следующие скелетные сущности JPA, поддерживаемые hibernate на Wildfly 18 (Hibernate 5.3.6). Я работаю над методом извлечения одной из сущностей, но отношение @OneToOne вызывает поиск дополнительных отдельных сущностей. Вот мои классы сущностей.

//table for tracking calendar terms
@Entity
@Table(name="calendar")
public class Calendar {

  @Id
  @Column(name = "term_id")
  private String termId;

  ... other non key fields omitted ...
}

//Table for tracking users
@Entity
@Table(name = "user")
public Class User {

  @Id
  @Column(name = "user_id")
  private String userId;

  ... other non key fields omitted ...
}

//Table for tracking organizations in the system
@Entity
@Table(name="organization")
public class Organization {

  @Id
  @Column(name = "organization_id")
  private String organizationId;

  @Column(name="term_id")
  private String termid;

  //Potentially null entity since the term id might not exist
  @OneToOne
  @JoinColumn(table="organization", name="term_id", referencedColumnName="term_id", updatable=false, 
              insertable=false, 
              foreignKey = @javax.persistence.ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
  @NotFound(action=NotFoundAction.IGNORE)
  private Calendar ;

  ... other fields omitted ...
}

//Class for joining users and organizations
@Entity
@IdClass(OrgMemberPK.class)
@Table(name = "org_member")
public class OrgMember {

  @Id
  @Column(name = "organization_id")
  private String organizationId;

  //Potentially null entity since the organization_id might not exist
  @OneToOne
  @JoinColumn(table = "org_member", name = "organization_id", 
              referencedColumnName = "organization_id", updatable = false,
              insertable = false, 
              foreignKey = @javax.persistence.ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
  @NotFound(action = NotFoundAction.IGNORE)
  private Organization organization;

  @Id
  @Column(name = "user_id")
  private String userId;

  //Potentially null entity since the user_id might not exist
  @OneToOne
  @JoinColumn(table = "org_member", name = "user_id", 
              referencedColumnName = "user_id", updatable = false, insertable = false, 
              foreignKey = @javax.persistence.ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
  @NotFound(action = NotFoundAction.IGNORE)
  private String user;
}

//Primary key class for org_member table    
public Class OrgmemberPK {
  private String organizationId;
  private String userId;
}

Я хочу использовать построитель критериев для извлечения всех OrgMembers и связанных сущностей для данного идентификатора пользователя с использованием графа сущностей

public List<OrgMember> getOrgMemberById(EntityManager em, String userId) {
  CriteriaBuilder cb = em.getCriteriaBuilder();
  CriteriaQuery<OrgMember> c = cb.createQuery(OrgMember.class);
  Root<OrgMember> root = c.from(OrgMember.class);

  //Build entity graph
  EntityGraph<OrgMember> graph = em.createEntityGraph(OrgMember.class);
  graph.addAttributeNodes(OrgMember_.user);
  Subgraph<Organization> subGraph = graph.addSubgraph(OrgMember_.organization);
  subGraph.addAttributeNodes(Organization_.term);

  c.where(cb.equals(root.get(OrgMember_.userId), userId));
  TypedQuery<OrgMember> query = em.createQuery(c);
  query.setHint("javax.persistence.loadgraph", graph);
  return query.getResultsList();
}

Когда Я включаю ведение журнала в спящем режиме и вижу, что генерируется следующее SQL

select
  orgmember0_.organization_id as organiza1_10_0_,
  orgmember0_.user_id as user_id2_10_0_,
  organizati1_.organization_id as organiza1_11_1_,
  calendar2_.term_id as term_id1_0_2_,
  user3_.user_id as user_id1_19_3_,
  ... omitted extra orgmember columns ...
  ... omitted extra organization columns ...   
  ... omitted extra calendar columns ...
  ... omitted extra user columns ...
from
  org_member orgmember0_
left outer join
  organization organizati1_
    on orgmember0_.organization_id=organizati1_.organization_id
left outer join
  calendar calendar2_
    on organizati1_.term_id=calendar2_.term_id
left outer join
  user user3_
    on orgmember0_.user_id=user3_.user_id
where
  orgmember0_.user_id=?

. На данный момент все данные для четырех сущностей доступны в запросе, но по какой-то причине он ищет значение для каждый найденный календарь.

select 
  calendar0_.term_id as term_id1_0_0_, 
  ... non key fields omitted ...
from 
  calendar calendar0_           
where 
  calendar0_.term_id=?

select 
  calendar0_.term_id as term_id1_0_0_, 
  ... non key fields omitted ...
from 
  calendar calendar0_           
where 
  calendar0_.term_id=?

select 
  calendar0_.term_id as term_id1_0_0_, 
  ... non key fields omitted ...
from 
  calendar calendar0_           
where 
  calendar0_.term_id=?

select 
  calendar0_.term_id as term_id1_0_0_, 
  ... non key fields omitted ...
from 
  calendar calendar0_           
where 
  calendar0_.term_id=? 

Почему отношение OneToOne от организации к календарю приводит к дополнительному поиску для каждого найденного календаря? Эта информация уже доступна в результатах, поскольку таблица объединена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...