我有一个看起来像
的实体@Entity
@Table(name = "log_entry")
public class LogItem {
@Id
@Column(name = "id")
private long id;
@Column(name = "request_id", nullable = false)
private String requestId;
@Column(name = "request_type")
@Enumerated(EnumType.STRING)
private RequestType requestType;
@Column(name = "entry_type")
@Enumerated(EnumType.STRING)
private LogType logType;
@Column(name = "operation_name")
private String operationName;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "time_stamp", nullable = false)
private Date timeStamp;
@Column(name = "attr_1")
private String attr1;
@Column(name = "attr_2")
private String attr2;
// ...
@Column(name = "attr_10")
private String attr10;
}
这映射到一个包含审计记录的表,通常会有一个根行和一堆插入了相同requestId的行,其中包含不同的logType,requestType和operationName值。 attrX列根据所涉及的类型/操作保持不同的值。
我需要实现一个通用查询工具,可以找到根据attrs的值查找根请求和一个或多个特定子元素。但是,我很难简单地将日志表加入到自身中。
我坚持的一点是试图模仿以下内容:
SELECT l1.*, l2.* FROM log_entry l1
JOIN log_entry l2
ON l2.request_id = l1.request_id
AND l2.entry_type = 'Something'
AND l2.operation_name = 'someOperation'
WHERE l2.operation_name = 'someOtherOperation'
这是我的代码
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<LogItem[]> criteria = cb.createQuery(LogItem[].class);
Root<LogItem> root = criteria.from(LogItem.class);
Join<LogItem, LogItem> responseJoin =
root.join(LogItem.requestId.getName(), JoinType.INNER);
ArrayList<Predicate> predicates = new ArrayList<Predicate>();
// Simply adds preciates for log type etc...
getCommonPredicates(filter, cb, root, predicates);
// Add predicates for attr values
addAttributePredicates(cb, predicates, filter.getAttributeFilters());
criteria.where(predicates.toArray(new Predicate[predicates.size()]));
TypedQuery<LogItem[]> query = entityManager.createQuery(criteria);
List<LogItem[]> resultsList = query.getResultList();
然而,这给了我错误:
org.hibernate.jpa.criteria.BasicPathUsageException:无法加入基本类型的属性
我知道我可以通过向实体类添加LogItem引用来解决这个问题,但我无法修改表结构。有没有办法在不恢复JBDC的情况下执行此操作? SQL是微不足道的我只是看不出如何将其转换为标准。我正在使用hibernate,而我更喜欢JPA解决方案,我并不反对使用特定于hibernate的代码。
答案 0 :(得分:1)