求助:HQL查询出现unexpected token: new语法异常问题
嘿,这个问题我之前排查过类似的,咱们直接说重点:
异常原因
你碰到的QuerySyntaxException本质是HQL不支持在select new的构造函数参数里嵌套多层new实例化自定义类。看你的HQL语句,在构造UserRequestEntity的时候,直接把new UserViewEntity(...)当成参数传进去,而UserViewEntity里又嵌套了new ContactViewEntity_(...)——这种多层嵌套的构造写法超出了HQL语法的解析能力,所以解析器在碰到第二个new的时候直接报错了。
解决办法
给你三个可行的方案,按需选择:
方案1:拆分查询+代码层组装(最通用)
先把需要的字段都查出来,不在HQL里搞嵌套构造,拿到结果后在Java代码里手动组装嵌套对象。
修改后的HQL:select generatedAlias0.user.email, generatedAlias0.user.contact.firstName, generatedAlias0.user.contact.lastName from com.test.user.request.api.entity.UserRequestEntity generatedAlias0然后在查询代码里处理:
List<Object[]> results = query.getResultList(); List<UserRequestEntity> resultEntities = new ArrayList<>(); for (Object[] row : results) { ContactViewEntity_ contact = new ContactViewEntity_((String) row[1], (String) row[2]); UserViewEntity userView = new UserViewEntity((String) row[0], contact); resultEntities.add(new UserRequestEntity(userView)); }方案2:用ResultTransformer做结果转换(适合Hibernate旧版本)
自定义一个结果转换器,把查询返回的字段直接映射成嵌套对象:Query query = session.createQuery(yourFieldBasedHql); // 先改成查字段的HQL query.setResultTransformer(new ResultTransformer() { @Override public Object transformTuple(Object[] tuple, String[] aliases) { // 按字段顺序组装嵌套对象 ContactViewEntity_ contact = new ContactViewEntity_((String) tuple[1], (String) tuple[2]); UserViewEntity userView = new UserViewEntity((String) tuple[0], contact); return new UserRequestEntity(userView); } @Override public List transformList(List collection) { return collection; } }); List<UserRequestEntity> results = query.list();方案3:用静态工厂方法封装构造逻辑(优雅但有代码侵入)
给顶层实体类加一个静态工厂方法,把嵌套构造的逻辑放到Java里,HQL只调用这个方法:public class UserRequestEntity { // 假设你有对应的构造函数 public UserRequestEntity(UserViewEntity userView) { // ... 初始化逻辑 } public static UserRequestEntity fromUserInfo(String email, String firstName, String lastName) { ContactViewEntity_ contact = new ContactViewEntity_(firstName, lastName); UserViewEntity userView = new UserViewEntity(email, contact); return new UserRequestEntity(userView); } }对应的HQL写法:
select com.test.user.request.api.entity.UserRequestEntity.fromUserInfo( generatedAlias0.user.email, generatedAlias0.user.contact.firstName, generatedAlias0.user.contact.lastName ) from com.test.user.request.api.entity.UserRequestEntity generatedAlias0
内容的提问来源于stack exchange,提问作者Soluna
相关产品推荐
相关产品推荐

