2012-01-04 22 views
2

我想做一個簡單的JPA會員查詢,但我不能爲我的生活得到它的工作。 Hibernate用消息「引用未保存的瞬態實例 - 在刷新之前保存實例:標記」消息拋出一個TransientObjectException異常。查詢如下:JPA會員與查詢分離的實體

public Collection<ItemDescription> getItems(){ 
    String entityClass = "ItemDescription"; 
    TypedQuery<ItemDescription> query = entityManager.createQuery(
      "SELECT i FROM " + entityClass +" i " + 
      "WHERE :tag MEMBER OF i.tags", ItemDescription.class); 
    query.setParameter("tag", new Tag("category:test")); 
    List<ItemDescription> resultList = query.getResultList(); 
    return resultList; 
} 

兩個實體類如下所示:當我使用從實體管理器作爲查詢參數檢索的Tag對象

@Entity 
@Table(name = "tags") 
public class Tag extends AbstractDomainEntity { 
    private static final long serialVersionUID = 2632379096725992272L; 
    private String value; 
    ... 
} 

@Entity 
@Table(name = "itemdescriptions") 
public class ItemDescription extends AbstractDomainEntity { 
    private static final long serialVersionUID = 9164310940207023539L; 
    private Set<Tag> tags = new HashSet<Tag>(); 
    ... 
    @OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL, orphanRemoval = true) 
    public Set<Tag> getTags() { 
     return tags; 
    } 
    private void setTags(Set<Tag> tags) { 
     this.tags = tags; 
    } 
} 

同樣的查詢工作。 「標籤」參數是否真的必須是託管實體?爲什麼?我怎樣才能使查詢工作?謝謝你們的幫助!

[編輯:] 謝謝你的提示。我現在結束了這個查詢:

public Collection<ItemDescription> getItems(){ 
    String entityClass = "ItemDescription"; 
    TypedQuery<ItemDescription> query = entityManager.createQuery(
      "SELECT i FROM " + entityClass +" i " + 
      "JOIN i.tags t " + 
      "WHERE t.value = :tag", ItemDescription.class); 
    query.setParameter("tag", "category:test"); 
    List<ItemDescription> resultList = query.getResultList(); 
    return resultList; 
} 

回答

1

正如Nayan Wadekar所述,:memberParameter MEMBER OF i.tags需要持久實例。

所以這裏有兩種解決方案。

  1. 確保您傳入一個Tag對象的已經存在的實例。
  2. 如果你不能做到這一點,你可以通過「tag'名通過JOIN查詢查詢:

    SELECT i FROM ItemDescription i JOIN c.tags t 
    WHERE t.name LIKE :name 
    
1

當事務提交時,持久化上下文中的所有對象都與基礎數據庫同步。因此,當您設置由實體管理器檢索的對象工作正常時,因爲對象處於受管狀態。

在這裏,您正在創建一個新對象&將其設置爲事務中查詢的參數,導致異常,因爲對象被分離。

從文檔:

當用戶經過一個短暫的實例會話方法 期望一個持久實例拋出。

+0

謝謝您的回答。我認爲這是支持的,因爲我已經在這裏看到了這樣一個例子[持久性回報:與JPA的高級映射](http://www.devx.com/Java/Article/33906/1763/page/2)所以我猜他例子也行不通。 – Sbhklr 2012-01-04 19:23:23