2013-11-02 50 views
0

查詢1(工作正常!):JPA JPQL查詢,其中object1 = Object2的

em.createQuery(
      "SELECT r FROM Route r WHERE r.start.x = :x" 
      , Route.class).setParameter("x", start.getX()) 

QUERY2(ID真的很喜歡這個工作!):

em.createQuery(
      "SELECT r FROM Route r WHERE r.start = :x" 
      , Route.class).setParameter("x", start) 
      .setMaxResults(20) 

拋出: TransientObjectException :對象引用未保存的瞬態實例 - 在沖刷前保存瞬態實例

路由實體:

@Entity 
@XmlRootElement(name="route") 

@XmlAccessorType(XmlAccessType.NONE) 
public class Route { 
private Long id; 
private User user; 
private Location start; 
private Location finish; 

public Route() { 
} 

@Id 
@GeneratedValue 
public Long getId() { 
    return id; 
} 

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

@ManyToOne 
@JoinColumn 
public User getUser() { 
    return user; 
} 

public void setUser(User user) { 
    this.user = user; 
} 

@OneToOne(cascade=CascadeType.PERSIST) 
public Location getStart() { 
    return start; 
} 

public void setStart(Location start) { 
    this.start = start; 
} 

@OneToOne(cascade=CascadeType.PERSIST) 
public Location getFinish() { 
    return finish; 
} 

public void setFinish(Location finish) { 
    this.finish = finish; 
} 

}

地點:

@Entity 
public class Location { 

@Id 
@GeneratedValue 
private Long id; 

private double x; 

private double y; 

public Location() { 
} 

public Location(double x, double y) { 
    this.x = x; 
    this.y = y; 
} 

@XmlTransient 
public double getX() { 
    return x; 
} 

public void setX(double x) { 
    this.x = x; 
} 

public double getY() { 
    return y; 
} 

public void setY(double y) { 
    this.y = y; 
} 

public boolean equals(Object o) { 
    if ((o instanceof Location) 
      && (((Location)o).getX() == this.x) 
      && (((Location)o).getY() == this.y)) 
    { 
     return true; 
    } 
    else return false; 
} 

}

+0

什麼是「開始」變量?你爲什麼不在第二個例子中調用'getX()'方法? – fracz

+0

「開始」是從HTTP POST數據收到的位置類實例...例如。與Location start = new Location(「1.0」,「1.0」)相同; ...我沒有使用getx(),因爲我想能夠測試複雜對象的相等性...... –

回答

0

TransientObjectException被拋出。由於Class Route被標註爲@Entity,因此查詢已將第一個對象視爲臨時對象(因爲它沒有設置@id字段)。

1

異常沒有太多做的查詢本身。

它拋出,因爲執行查詢之前,Hibernate的刷新都沒有被刷新尚未改變。並且不能這樣做,因爲...對象引用未保存的瞬態實例。因此,請確保在執行查詢之前保存瞬態實例。時所通過的構造實例化類正在從數據庫讀出的同一類的同一對象進行比較

+0

嗯,我可以看到Route,它的開始屬性(以及所有其他相關實體)被持久化數據庫在運行查詢之前...所以我沒有看到可能是那個瞬態實例。 –

+0

使用調試器逐句通過代碼,並嘗試跟蹤所有連接到受管理的實體但在執行查詢之前不會執行持久化的實體。 –

+0

在運行查詢之前,我只有一個實體持久化:「用戶」,用戶有1個路由,路由有一個開始和結束位置。一旦我調用em.getTransaction()。commit();我可以在數據庫中看到他們全部。如果我嘗試調用em.flush,jboss會告訴我沒有活動事務。所以我可以調用em.close()。稍後創建新的EntityManager以運行有問題的查詢。我懷疑可能錯誤是由於由「POST」數據收到的「start」(Location類)引用的Location,並且id = null。但我覺得這個理論有點牽強。 –