2016-02-01 6 views
0

у меня есть объект, который выглядит как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(); 

Это, однако, дает мне ошибку:

орг. hibernate.jpa.criteria.BasicPathUsageException: не может присоединиться к атрибуту базового типа

Я понимаю, что могу обойти это, добавив ссылки LogItem к сущностному классу, но я не могу изменить структуру таблицы. Есть ли способ сделать это, не обращаясь к JBDC? SQL тривиально, я просто не вижу, как преобразовать его в критерии. Я использую спящий режим, в то время как я бы предпочел решение JPA, я не против использования спящего режима.

+0

и что имеет log_item, связанное с log_entry? –

+0

Опечатка, я набрал аннотации объектов, а не копировать и вставлять. Применяется только одна организация. – vickirk

+0

, очевидно, вы не можете использовать JOIN в поле отношений, как и во всех документах. Вы можете добавить еще один класс из() и добавить предложение where. –

ответ

1

Вы можете только join через отношение 1-1/1-N/M-N/N-1, поскольку JPA пытается сохранить дух O-O. Ваши варианты здесь

  • Добавить дополнительный from пункт и указать пункт where сопровождать его. Вероятно, это создаст CROSS JOIN.
  • Добавьте отношение к своей модели, чтобы вы могли использовать join() и определить INNER или LEFT OUTER.

Понятно, что некоторые из этих параметров могут быть недоступны для вашей ситуации.

Смежные вопросы