让我以此开头作为开头,说我是Spring的新手,并且不确定如何提出这个问题。所以去了:
我正在使用Spring Boot 1.5.22和PostgreSQL 9.5。该程序用于获取通过与该邀请相关联的元数据过滤的电子邮件发送的邀请。因此,存在一个实体Invitation
与oneToMany
有一个Metadata
关联。
我正在尝试使用Querydsl来构建将Invitation
与过滤后的Metadata
连接起来的谓词。在我负责使用NamedEntityGraph优化查询之前,这种方法就可以工作了。现在,Hibernate抱怨要尝试查找Metadata
上确实存在的Invitation
不存在的属性。
这些是相关实体:
// invitation
@Entity
// the query uses this entity graph
@NamedEntityGraph(
name = "Invitation.detail",attributeNodes = {
@NamedAttributeNode(value = "metadata")
}
)
@Table(name="invitation")
public class Invitation implements Serializable {
@OneToMany(fetch = FetchType.LAZY,mappedBy = "invitation",cascade = CascadeType.ALL)
private List<Invitationmetadata> metadata = new ArrayList<Invitationmetadata>();
/* ... */
}
// metadata
@Entity
@Table(name="metadata")
public class Metadata implements Serializable {
@Column(name="key")
private String key;
@Column(name="value")
private String value;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "invitationId")
private Invitation invitation;
}
这是查询方式:
// in implementation
public Page<Invitation> getData(Map<String,List<String>> metadataFilters,List<String> ids) {
Pageable pageable = createPageRequest(); // page of 1000 items
QInvitation attempt = QInvitation.invitation; // Querydsl query type
BooleanBuilder predicate = new BooleanBuilder();
builder.and(attempt.id.in(ids));
for (String key : metadataFilters.keySet()) {
builder.and(attempt.metadata.any().metadataKey.equalsIgnoreCase(key)); // this is where the error is thrown,when EntityGraph is used
builder.and(attempt.metadata.any().metadataValue.in(metaFilters.get(key)));
}
Page<Invitation> invitations = invitationRepository.findAll(predicate.getvalue(),pageable);
return invitations;
}
// repository
@Repository
interface InvitationRepository extends JpaRepository<Invitation,Long>,InvitationRepositoryCustom,QueryDslPredicateExecutor<Invitation> {
@EntityGraph(value = "Invitation.detail",type = EntityGraph.EntityGraphType.LOAD)
public Page<Invitation> findAll(Predicate predicate,Pageable pageable);
/* ... */
}
// Querydsl query type
public class QInvitation extends EntityPathBase<Invitation> {
public final ListPath<Metadata,QMetadata> metadata = this.<Metadata,QMetadata>createList("metadata",Metadata.class,QMetadata.class,PathInits.DIRECT2);
}
这是收到的错误:
org.hibernate.QueryException: could not resolve property: metadata of: foo.bar.data.jpa.domain.Metadata
如您所见,Invitation
存在属性“ metadata”,但它试图在Metadata
中找到它。在我看来,Hibernate似乎正在尝试将我的EntityGraph(Invitation.detail)应用到联接表上。我试图搜索答案,但是很难为此找到一个搜索词。
就像我说的那样,如果不使用EntityGraph,则此查询将按预期工作。另外,如果我完全不使用metadataFilters
,则查询将执行。
有人知道吗?希望您理解我要问的问题。