问题描述
我想用 QueryDSL
创建谓词,但我不知道为什么,但某些嵌套字段为 NULL:
BooleanExpression emailSender = qFreight.message.account.user.id.eq(userId);
用户为空。
qFreight.message.account.user
给我 NPE 错误
然后在日志中我有
.180 ERROR 7316 --- [nio-9090-exec-3] p.a.m.s.filter.JwtAuthorizationFilter : Request processing Failed; nested exception is java.lang.NullPointerException
当然我已经生成了QFreight
、QMessage
、QAccount
、QUser
……哪里可以打赌这个问题?我没有任何想法
更新
我的实体(问题是如何正确设置@QueryInit):
@Entity
@Table(name = "freight")
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Freight {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false,updatable = false)
private Long id;
@QueryInit("*")
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "message_id")
private Message message;
@OnetoOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
}
@Entity
@Table(name="message")
@Getter
@Setter
public class Message {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false,updatable = false)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "email_account_id",foreignKey = @ForeignKey(name = "FK_account_to_message"))
private Account account;
}
@Entity
@Table(name="account")
@Getter
@Setter
@NoArgsConstructor
@SuperBuilder(builderMethodName = "of")
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false,updatable = false)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
private User user;
}
解决方法
qFreight.message.account.user.id
不是有效的 JPQL 表达式。您必须明确创建实体之间的连接:JOIN qFreight.message message JOIN message.account account JOIN account.user user
。在 QueryDSL 中,这将是:.join(qFreight.message,QMessage.message).join(QMessage.message.account,QAccount.account).join(QAccount.account.user,QUser.user).where(QUser.user.id.eq(...))
.
此外,默认情况下 QueryDSL 元模型仅初始化一级深度。这是性能决定。如果您需要更深入地初始化元模型(即使用例很少,因为 JPQL 缺乏对隐式连接的支持),您必须使用 @QueryInits
:http://www.querydsl.com/static/querydsl/4.4.0/reference/html_single/#d0e2265