Hi All,
I'm having a problem passing a collection to the constructor in a select clause. I have two classes which look minimally like this. (getters and setters omitted for brevity)
@Entity public class User{
@Id @GeneratedValue(strategy = GenerationType.AUTO) private int id;
private String username;
@ManyToOne(optional=false,fetch = FetchType.LAZY) private Organisation company;
@ManyToMany private Set<SecurityGroup> securityGroups = new HashSet<SecurityGroup>();
public User(String username, Set<SecurityGroup> securityGroups){ this.username = username; this.securityGroups = securityGroups; }
}
@Entity public class SecurityGroup{
@Id @GeneratedValue(strategy = GenerationType.AUTO) private int id;
private String name;
@ManyToMany (mappedBy="securityGroups") private List<User> users;
}
I have lots of other properties in the User that I don't want to fetch with each query. So I'm trying to minimize the amount of data loaded. Here are the different query scenarios and exceptions I get
1. When I execute the following query: select new com.test.User(o.username, o.securityGroups) from User o left join o.securityGroups s where o.company.id=:companyId
I get the following exception: org.hibernate.util.JDBCExceptionReporter:101 - You have an error in your SQL syntax
(this is a named query with companyId set appropriately. Everything works fine if I don't pass the securityGroups in the constructor)
2. When the query is changed to: select new com.test.User(o.username, s) from User o left join o.securityGroups s where o.company.id=:companyId
I get this exception at deployment time: org.hibernate.hql.ast.QuerySyntaxException: Unable to locate appropriate constructor on class [com.test.User]
3. When the constructor is changed to public User(String username, Object securityGroups)
The application deploys alright, but I get this exception when the query is executed: java.lang.IllegalArgumentException: org.hibernate.QueryException: could not instantiate class [com.test.User] from tuple
However following example in the hibernate documentation suggests that a collection can be passed in a constructor specified in a select clause: select new Family(mother, mate, offspr) from DomesticCat as mother join mother.mate as mate left join mother.kittens as offspr
I guess my question is: is what I'm trying to do supported and if so, what am I doing wrong?
Any help is very much appreciated! Thanks.
|