2014-11-21 110 views
1

我有兩個表:SegmentObservation。 段可以有多個觀察值,1到N關係(segment_id是Observation表中的外鍵)。我必須驗證給定的時間戳和給定的段是否有觀測值。JPA查詢加入表

觀測類別如下:

@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查詢?

回答

2

在某些(可能全部)JPA實現字段區分大小寫。

所以,你的FROM子句中應即

FROM Observation o JOIN o.segment s 

o.segment代替o.Segment

1

嘗試

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

在這種情況下,你應該送Segment類型的對象作爲參數,而不是它的ID。