У меня есть система, которая загружает данные из файлов в реляционную базу данных, чтобы проверить целостность отношений, чтобы идентифицировать и удалить отношения без родителя. У меня есть следующие скелетные сущности 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 от организации к календарю приводит к дополнительному поиску для каждого найденного календаря? Эта информация уже доступна в результатах, поскольку таблица объединена.