BeanUtils uses the Introspector (core java) to populate your beans. It will use your setXs(index, object) and getXs(index) methods if you supply them (see http://java.sun.com/j2se/1.4.2/docs/api/java/beans/IndexedPropertyDescriptor.html). Since HashSet does not guarantee the order of your set will remain constant, I'd use a java.util.LinkedHashSet if I was you.
If you provide the implementation for the following methods, you should be fine. public class Role extends ValidatorActionForm { private Set users = new LinkedHashSet(); public Set getUsers() {} public void setUsers(Set users) {} public String getUsers(int index) {} public void setUsers(int index, String user) {} } Another simpler option is to use a List or an array on your form and move it to a Set when you process it in your middle tier. Lance. -----Original Message----- From: Abbas Adel [mailto:[EMAIL PROTECTED] Sent: 02 February 2007 23:55 To: commons-user@jakarta.apache.org Subject: Struts+Hibernate many-to-many mismatch Dears, I have 2 hibernate entities, user & role, with many-to-many relation. I also use them as form beans. [code] public class User extends ValidatorActionForm { private int UID; private String username; private String password; private String name; private String email; private Set roles; . } public class Role extends ValidatorActionForm { private int RID; private String name; private Set users; . } [/code] I created a simple Struts form to insert new user [code] <html:form action="/InsertUser" method="post"> Username: <html:text property="username" /> Password: <html:password property="password" /> Name: <html:text property="name" /> Email: <html:text property="email" /> Roles: <html:select property="roles" multiple="true"> <html:optionsCollection name="roles" label="name" value="RID" /> </html:select> <html:submit/> </html:form> [/code] When I run this form, struts complains [i]"argument type mismatch" [/i] because it doesn't know how to convert the roles property, which is String[], into java.util.Set I had to write my own BeanUtil type convertor to convert from String[] to java.util.Set. [code] public class RolesListConverter extends AbstractArrayConverter { public Object convert(Class type, Object value) { try { List list = parseElements(value.toString()); String results[] = new String[list.size()]; Set results = new HashSet(list.size()); for (int i = 0; i < list.size(); i++) { results[i] = (String) list.get(i); results.add(Role (Integer.parseInt((String)list.get(i)))); } return (results); } catch (Exception e) { if (useDefault) { return (defaultValue); } else { throw new ConversionException(value.toString(), e); } } } } [/code] Then struts didn't complain but the roles Set was populated with 1 role only regardless of how many roles were selected. I gave a closer look at org.apache.commons.beanutils.BeanUtilsBean.java to see how it works. I found this: [code] else if (type.isArray()) { // Indexed value into array if (value instanceof String) { newValue = getConvertUtils().convert((String) value, type.getComponentType()); } else if (value instanceof String[]) { newValue = getConvertUtils().convert(((String[]) value)[0], type.getComponentType()); [/code] Because java.util.Set is not an array "Set.class.isArray() return false" then treat the "String[] value" as a single-value array "value[0]" So, what do you suggest to force struts to convert String[] to Set? Thanks in advance BISO Student @ Menufia University org.apache.commons.beanutils.BeanUtilsBean.java [code] . 976 if (type.isArray() && (index < 0)) { // Scalar value into array if (value == null) { String values[] = new String[1]; values[0] = (String) value; newValue = getConvertUtils().convert((String[]) values, type); } else if (value instanceof String) { String values[] = new String[1]; values[0] = (String) value; newValue = getConvertUtils().convert((String[]) values, type); } else if (value instanceof String[]) { newValue = getConvertUtils().convert((String[]) value, type); } else { newValue = value; } } else if (type.isArray()) { // Indexed value into array if (value instanceof String) { newValue = getConvertUtils().convert((String) value, type.getComponentType()); } else if (value instanceof String[]) { 1004 newValue = getConvertUtils().convert(((String[]) value)[0], type.getComponentType()); } else { newValue = value; } } else { // Value into scalar if ((value instanceof String) || (value == null)) { newValue = getConvertUtils().convert((String) value, type); } else if (value instanceof String[]) { newValue = getConvertUtils().convert(((String[]) value)[0], type); } else if (getConvertUtils().lookup(value.getClass()) != null) { newValue = getConvertUtils().convert(value.toString(),type); } else { newValue = value; } } . [/code] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]