我正在尝试编写一个接受动态谓词的通用DAO类。
在我的BaseDAO类中,我创建PathBuilder
来使用以下构造函数添加一些谓词:PathBuilder<Q> entityPath = new PathBuilder<Q>(clazz, "entity");
执行时,出现以下异常:
2019-06-06 17:55:11.779错误11212 --- [http-nio-8080-exec-2] o.a.c.c.C。[。[。[/]。[dispatcherServlet]:的Servlet.service() 路径[]中的servlet [dispatcherServlet]抛出异常 [请求处理失败;嵌套异常为 org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.ast.QuerySyntaxException:无效的路径: 'entity.id' [从com.example.clientcachedemo.Member中选择member1 member1,其中entity.id =?1];嵌套异常为 java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException:无效的路径: 'entity.id'[从com.example.clientcachedemo.Member中选择member1 member1,其中entity.id =?1]]的根本原因
org.hibernate.hql.internal.ast.QuerySyntaxException:无效的路径: 'entity.id'[从com.example.clientcachedemo.Member中选择member1 member1,其中entity.id =吗?1]
在构造HQL时,休眠似乎使用了“ member1”作为表别名。
如果我将PathBuilder的创建更改为PathBuilder<Q> entityPath = new PathBuilder<Q>(clazz, "member1");
,则一切正常,但这应该是通用代码。
如何推断休眠使用的表的别名?
如何强制休眠使用其他别名(“实体”)?
public abstract class BaseEntity implements Serializable {
private static final long serialVersionUID = -5322749711870322616L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id", nullable = false, columnDefinition = "BIGINT UNSIGNED")
protected Long id;
@UpdateTimestamp
public Timestamp timestamp;
@Version
Long version;
}
@Data
@Entity
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Table(name = "MEMBERS", indexes = { @Index(name = "ix1", unique = false, columnList = "timestamp") })
public class Member extends BaseEntity {
private static final long serialVersionUID = -3641904361081907333L;
private String name;
private String city;
private String email;
private String gender;
private String hour;
private String title;
}
public class BaseDAO<E extends BaseEntity, Q extends EntityPath<?>> {
@Autowired
BaseQDSLRepository<E, Q> repository;
public Iterable<E> query(RestCriteria criteria) {
Class<E> clazz = getEntityClass();
PathBuilder<E> entityPath = new PathBuilder<E>(clazz, "entity");
Predicate p = entityPath.get("id").eq(1L); // TODO Parse criteria to predicate...
return repository.findAll(p);
}
@SuppressWarnings({ "unchecked" })
protected Class<E> getEntityClass() {
Class<E> clazz = null;
Type[] genericTypes = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments();
if (genericTypes[0] instanceof ParameterizedType) {
clazz = (Class<E>) ((ParameterizedType) genericTypes[1]).getRawType();
} else {
clazz = (Class<E>) genericTypes[0];
}
return clazz;
}
}
@NoRepositoryBean
public interface BaseQDSLRepository<E extends BaseEntity, Q extends EntityPath<?>>
extends BaseJpaRepository<E>, QuerydslPredicateExecutor<E>, BinderCustomizer<Q> {
}
@PostMapping
@ResponseBody
public Iterable<Member> query(@RequestBody RestCriteria criteria) {
Iterable<Member> mems = dao.query(criteria);
return mems;
}