使用原始类型加入自我的JPA标准

时间:2016-02-01 10:47:40

标签: java jpa

我有一个看起来像

的实体
@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的代码。

1 个答案:

答案 0 :(得分:1)

你只能通过1-1 / 1-N / M-N / N-1关系加入,因为JPA试图保持O-O的精神。你的替代品是 添加一个额外的from子句并指定一个where子句 它。这可能会创建一个CROSS JOIN。 为模型添加关系,然后您可以使用join()并定义INNER或LEFT OUTER。 显然,其中一些可能不适合您的情况。