2012-08-14 98 views
1

我使用的是spring roo生成控制器.. 映射定義如下。Spring Roo多對多的搜索對象引用未保存的瞬態實例

Class users 
    private String username; 
    private String password; 

@ManyToMany(fetch = FetchType.EAGER) 
    @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE) 
    @JoinTable(name = "user_roles", 
     joinColumns = { @JoinColumn(name = "users_id") }, 
     inverseJoinColumns = { @JoinColumn(name = "roles_id") }) 
    private Set<Authority> roles = new HashSet<Authority>(); 

Class Authority 
    private String roles 
    private String descricao; 

@ManyToMany(fetch = FetchType.EAGER , mappedBy = "roles") 
    @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE) 
    private Set<Users> users = new HashSet<Users>(); 

的關係的工作,即填充這個表「用戶」和表服務「Users_roles」,而不是真正管理局預計表。

數據的持久性完美,它是由Spring roo生成的方式, 控制器的用戶以這種方式工作。

Users users = Users.fromJsonToUsers(json); 
    users.persist(); 

嘗試通過使用關係的方法執行搜索時發生問題。

StringBuilder queryBuilder = new StringBuilder("SELECT o FROM Users AS o WHERE LOWER(o.username) LIKE LOWER(:username) AND LOWER(o.password) LIKE LOWER(:password)"); 
     queryBuilder.append(" OR"); 
     for (int i = 0; i < roles.size(); i++) { 
      if (i > 0) queryBuilder.append(" AND"); 
      queryBuilder.append(" :roles_item").append(i).append(" MEMBER OF o.roles"); 
     } 
     TypedQuery<Users> q = em.createQuery(queryBuilder.toString(), Users.class); 
     q.setParameter("username", username); 
     int rolesIndex = 0; 
     for (Authority _authority: roles) { 
      q.setParameter("roles_item" + rolesIndex++, _authority); 
     } 
     q.setParameter("password", password); 
     return q; 

形成這樣的查詢:

(
    SELECT o 
    FROM Users AS o 
    WHERE LOWER(o.username) LIKE LOWER(:username) 
    AND LOWER(o.password) LIKE LOWER(:password) 
    OR :roles_item0 MEMBER OF o.roles 
) 

例外:

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.Transi 
entObjectException: **object references an unsaved transient instance - save the t 
ransient instance before flushing:** br.teste.carro.domain.Authority; neste 
d exception is java.lang.IllegalStateException: org.hibernate.TransientObjectExc 
eption: object references an unsaved transient instance - save the transient ins 
tance before flushing: br.teste.carro.domain.Authority 

我懷疑,這個問題是我如何保存的方式,但不能肯定。 如果有人能夠使用Force,我將不勝感激。

回答

0

你需要指定在RELP兩側的連接列,他們應該對對方逆轉:

Class users 
@JoinTable(name = "user_roles", 
    joinColumns = { @JoinColumn(name = "users_id") }, 
    inverseJoinColumns = { @JoinColumn(name = "roles_id") }) 


Class Authority 
@JoinTable(name = "user_roles", 
    joinColumns = { @JoinColumn(name = "roles_id") }, 
    inverseJoinColumns = { @JoinColumn(name = "users_id") }) 
+0

我所提到那樣, 加兩側@ JoinTable,但如果我得標記mappedBy聲明爲 我得到運行時錯誤,如果你刪除標籤可以運行服務器。 但是錯誤仍然是暫時的對象在研究中爆炸並且不能使條目.. =/ 感謝您的回覆.... – 2012-09-19 14:23:31

相關問題