2012-08-14 94 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

相关问题