La mia ipotesi è vi manca l'implementazione per le equals
e hashcode
metodi sulla classe RoleEntity.
Quando il valore limite è di tipo array o java.util.Collection, l'ingresso (casella di controllo) è contrassegnato come 'controllato' se il valore configurato setValue (Object) è presente nella Collezione legato.
Questo è corretto, ma per verificare la presenza in un HashSet
è necessario equals
e hashcode
implementato correttamente.
Proprio come un test rapido per vedere se questo è il problema, sostituire questa linea:
model.addAttribute("roleList", roleList);
con questa linea:
model.addAttribute("roleList", userEntity.getRoles());
Non si ottiene tutte le caselle di controllo controllati? Se sì, allora non hai fornito il tuo equals
e hashcode
e quelli di default sono utilizzati (quelli ereditati da Object
).
Il valore predefinito equals
confronta l'identità, il che significa che una variabile contiene la stessa istanza di un'altra variabile. Uguaglianza significa che due oggetti diversi contengono lo stesso stato o hanno lo stesso significato, per così dire.
L'utilizzo di model.addAttribute("roleList", userEntity.getRoles())
attiva il metodo predefinito equals
per restituire true poiché l'elenco ei valori che si verificano per presenza nell'elenco sono identici (due oggetti identici sono sempre uguali).
Ma nel tuo caso si utilizza userEntityService.findById
per uno e roleEntityService.findAll
per l'altro che significa diversi oggetti. A questo punto devi usare un test di uguaglianza appropriato invece dell'identità.
Avete implementato equals
/hashcode
?
Sulla base di codice, ecco un esempio che funziona:
Controller:
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class SomeController {
@RequestMapping(value = "/something", method = { RequestMethod.GET, RequestMethod.POST })
public String handle(Model model) {
UserEntity userEntity = new UserEntity();
userEntity.setRoles(new HashSet<RoleEntity>());
Collections.addAll(userEntity.getRoles(),
new RoleEntity(1, "one"),
new RoleEntity(3, "three"));
model.addAttribute("userAttribute", userEntity);
List<RoleEntity> roleList = Arrays.asList(
new RoleEntity(1, "one"),
new RoleEntity(2, "two"),
new RoleEntity(3, "three")
);
model.addAttribute("roleList", roleList);
return "view";
}
}
classe User:
import java.util.HashSet;
import java.util.Set;
public class UserEntity {
private Set<RoleEntity> roles = new HashSet<RoleEntity>();
public Set<RoleEntity> getRoles() {
return roles;
}
public void setRoles(Set<RoleEntity> roles) {
this.roles = roles;
}
}
ruoli classe (preavviso la equals
e hashcode
metodi; se li rimuovi, il esempio non funziona più):
public class RoleEntity {
private long id;
private String name;
@Override
public int hashCode() {
return new Long(id).hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (! (obj instanceof RoleEntity)) {
return false;
}
return this.id == ((RoleEntity)obj).getId();
}
public RoleEntity(long id, String name) {
this.id = id;
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Vista:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<form:form modelAttribute="userAttribute" method="POST" action="/something">
<table align="center">
<tr>
<td>ID</td>
<td>Role Name</td>
</tr>
<c:forEach items="${roleList}" var="role">
<tr>
<td><form:checkbox path="roles" value="${role}" label="${role.id}" /></td>
<td><c:out value="${role.name}" /></td>
</tr>
</c:forEach>
</table>
</form:form>
P.S. Una sola osservazione sulla tua JSP. Se esegui lo value="${role}"
per il tuo modulo: checkbox otterrai gli attributi della casella di controllo HTML come value="[email protected]"
che potrebbero metterti in un altro tipo di problema in seguito.
Grazie mille, Bogdan. Questa risposta mi ha davvero aiutato !! Tuttavia, le caselle di controllo vengono verificate solo quando aggiungo i ruoli utente alla vista: model.addAttribute ("roleList", userEntity.getRoles()); ma non funziona con tutti i ruoli. –
@Paul Kuhn: prego. Ho aggiunto alcune spiegazioni come risposta al tuo commento per migliorare la risposta. [Qui] (http://tutorials.jenkov.com/java-collections/hashcode-equals.html) è una presentazione più dettagliata. Spero che aiuti a spiegare ulteriormente cosa stava causando il comportamento. – Bogdan