Таблицы присоединения запросов JPA

1

У меня две таблицы: Segment и Observation. Сегмент может иметь несколько наблюдений, отношение от 1 до N (segment_id - это внешний ключ в таблице Observation). Я должен проверить, есть ли для данной метки времени и данного сегмента наблюдения или нет.

Класс Наблюдения выглядит следующим образом:

@Entity
@Table(name="observation")
@NamedQuery(name="Observation.findAll", query="SELECT o FROM Observation o")
public class Observation implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(unique=true, nullable=false)
private int id;

@Column(nullable=false)
private byte observation;

@Column(name="observed_at", nullable=false)
private Timestamp observedAt;

//bi-directional many-to-one association to Segment
@ManyToOne
@JoinColumn(name="segment_id", nullable=false)
private Segment segment;

public Observation() {
}

public int getId() {
    return this.id;
}

public void setId(int id) {
    this.id = id;
}

public byte getObservation() {
    return this.observation;
}

public void setObservation(byte observation) {
    this.observation = observation;
}

public Timestamp getObservedAt() {
    return this.observedAt;
}

public void setObservedAt(Timestamp observedAt) {
    this.observedAt = observedAt;
}

public Segment getSegment() {
    return this.segment;
}

public void setSegment(Segment segment) {
    this.segment = segment;
}
}

Таблица Segment выглядит следующим образом:

@Entity
@Table(name="segment")
@NamedQuery(name="Segment.findAll", query="SELECT s FROM Segment s")
public class Segment implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=GenerationType.TABLE)
@Column(name="segment_id", unique=true, nullable=false)
private int segmentId;

private int dummy;

//bi-directional many-to-one association to Observation
@OneToMany(mappedBy="segment")
private List<Observation> observations;

public Segment() {
}

public int getSegmentId() {
    return this.segmentId;
}

public void setSegmentId(int segmentId) {
    this.segmentId = segmentId;
}

public int getDummy() {
    return this.dummy;
}

public void setDummy(int dummy) {
    this.dummy = dummy;
}

public List<Observation> getObservations() {
    return this.observations;
}

public void setObservations(List<Observation> observations) {
    this.observations = observations;
}

public Observation addObservation(Observation observation) {
    getObservations().add(observation);
    observation.setSegment(this);

    return observation;
}

public Observation removeObservation(Observation observation) {
    getObservations().remove(observation);
    observation.setSegment(null);

    return observation;
}
}

Обычно, в стандартном SQL я бы написал:

 SELECT COUNT(*)
 FROM Observation o, Segment s
 WHERE o.segment_id = s.segment_id
 AND  s.segment_id = segmentIdParam
 AND o.observed_at = observedAtParam
 AND o.observation = observationParam

Я хочу написать этот запрос, используя соединение JPA. Я написал следующее:

Query query = initEntityManager().createQuery(
                  "SELECT s "
                + "FROM Observation o JOIN o.Segment s "
                + "WHERE s.segmentId   = :segmentIdParam"
                +  " AND o.observedAt  = :observedAtParam"
                +  " AND o.observation = :observationParam", Observation.class);

    query.setParameter("segmentIdParam",   segmentId);
    query.setParameter("observedAtParam",  observedAt);
    query.setParameter("observationParam", observation);

К сожалению, я получаю исключение:

java.lang.IllegalArgumentException: An exception occurred while creating a query in     EntityManager: 
 Exception Description: Problem compiling [SELECT s FROM Observation o JOIN o.Segment s WHERE s.segmentId = :segmentIdParam AND o.observedAt = :observedAtParam AND o.observation = :observationParam ]. 
[33, 42] The collection-valued path 'o.Segment' cannot be resolved to a valid association field.
[51, 62] The state field path 's.segmentId' cannot be resolved to a valid type.

Как следует написать этот запрос JPA?

Теги:
jpa
join
jpql

2 ответа

2
Лучший ответ

В некоторых (возможно, всех) вариантах реализации JPA чувствительны к регистру.

Таким образом, ваше предложение FROM должно быть

FROM Observation o JOIN o.segment s

то есть вместо o.Segment

1

Пытаться

SELECT o FROM Observarion o 
    WHERE o.segment =: segmentParam
      AND o.observedAt =: observedAt
      AND o.observation =: observationParam

В этом случае вы должны отправить объект типа Segment как параметр, а не его идентификатор.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню