Bonjour à tous,

je suis confronté à un problème qui est le suivant :

- je mets en place une vue composé d'un datatable parcourant une liste d'objets A. Chaque objet A contient une propriété de type collection d'objet B (relation ManyToMany).

- la première colonne de ma table correspond au libellé de chacun de mes objets A.
- les colonnes suivantes (dynamic columns) correspondant à l'ensemble des objets B existants en base.
- Chaque cellule de rencontre entre mes objets A et B est un commandButton qui permet d'associer/dissocier les 2 types d'objet.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Entity
@Table(name = "T_ADM_CATEGORIE")
public class TAdmCategorie implements Serializable {
 
	private static final long serialVersionUID = 2396525655728706282L;
 
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO, generator="seqGenerator")
	@SequenceGenerator(name="seqGenerator", sequenceName="T_ADM_CATEGORIE_id_seq")
	@Column(name = "ID", unique = true, nullable = false)
	private int id;
 
	@Column(name = "CATEGORIE", nullable = false)
	private String libelle;
 
	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(name = "T_ADM_CAT_MOTIF", joinColumns = { @JoinColumn(name = "CATEGORIE_ID", nullable = false, updatable = false) },
		inverseJoinColumns = { @JoinColumn(name = "MOTIF_ID", nullable = false, updatable = false) })
	private Set<TRefMotifConvoc> motifConvocs;
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Entity
@Table(name = "T_REF_MOTIFCONVOC")
public class TRefMotifConvoc implements Serializable {
 
	private static final long serialVersionUID = 2145221707619795173L;
 
	@Id
	@Column(name = "MO1CONV", unique = true, nullable = false)
	private String code;
 
	@Column(name = "MOLCONV")
	private String libelle;
 
	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(name = "T_ADM_CAT_MOTIF", joinColumns = { @JoinColumn(name = "MOTIF_ID", nullable = false, updatable = false) },
		inverseJoinColumns = { @JoinColumn(name = "CATEGORIE_ID", nullable = false, updatable = false) })
	private Set<TAdmCategorie> categories;
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
@Controller
@Scope("view")
public class AdmTables implements Serializable {
 
	private static final long serialVersionUID = -721821642662339261L;
	private static final Logger logger = Logger.getLogger(AdmTables.class);
 
	private List<TAdmCategorie> categories;
	private List<TRefMotifConvoc> motifsConvoc;
 
	private List<ColumnModel> columns = new ArrayList<ColumnModel>();
 
	@Autowired
	private TAdmCategorieService categorieService;
 
	@Autowired
	private TRefService refService;
 
	@PostConstruct
	public void init() {
 
		try {
 
			categories = categorieService.getAll(); // recuperation liste categories
    			motifsConvoc = refService.getMotifsConvocation();  // recuperation motifs
 
    			createDynamicColumns();
		}
		catch (ServiceException se) {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_FATAL, se.getMessage(), null);
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}
	}
 
 
 
	/**
         * 
         * @param categorie
         * @param motif
         */
	public void addMotifToCategorie(TAdmCategorie categorie, TRefMotifConvoc motif) {
 
	}
 
	/**
         * 
         * @param categorie
         * @param motif
         */
	public void removeMotifToCategorie(TAdmCategorie categorie, TRefMotifConvoc motif) {
 
	}
 
 
	/**
         *
         */
	static public class ColumnModel implements Serializable {  
 
		private static final long serialVersionUID = 8804958064404272446L;
 
		private String header;  
        	private TAdmCategorie categorie;  
 
       	 	public ColumnModel(String header, TAdmCategorie categorie) {  
            		this.header = header;  
            		this.categorie = categorie;  
        	}  
 
        	public String getHeader() {  
            		return header;  
        	}  
 
        	public TAdmCategorie getCategorie() {  
            		return categorie;  
        	}  
    	}  
 
	/**
         * 
         */
	public void createDynamicColumns() {
 
        	columns.clear();
 
        	for (TAdmCategorie categorie : categories) {
        		columns.add(new ColumnModel(categorie.getLibelle().toUpperCase(), categorie));
			}
    	}
 
 
	// getters & setters
	public List<TAdmCategorie> getCategories() {
		return categories;
	}
 
	public void setCategories(List<TAdmCategorie> categories) {
		this.categories = categories;
	}
 
	public List<TRefMotifConvoc> getMotifsConvoc() {
		return motifsConvoc;
	}
 
	public List<ColumnModel> getColumns() {
		return columns;
	}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">
 
<h:body>
 
    <h:form id="categorieForm">
        <p:dataTable id="admCategorie" value="#{admTables.motifsConvoc}" var="motif">
 
            <p:column rowspan="2" headerText="Motifs de convocation">
                <h:outputText value="#{motif.libelle}"/>
            </p:column>
 
	        <p:columns value="#{admTables.columns}" var="column" columnIndexVar="colIndex" style="width: 30px; text-align: center;">
	            <f:facet name="header">
                    #{column.header}
                </f:facet>
 
                <ui:repeat var="motifCategorie" value="#{motif.categories.toArray()}" >
                    <p:commandLink id="removeButton" actionListener="#{admTables.removeMotifToCategorie(column.categorie, motif)}" rendered="#{motifCategorie eq column.categorie}"
                                   update=":admTables:categorieForm:admCategorie">
                        <p:graphicImage library="default" name="img/check.png" styleClass="iconCheck" />
                    </p:commandLink>
 
                    <p:commandLink id="addButton" actionListener="#{admTables.addMotifToCategorie(column.categorie, motif)}" rendered="#{motifCategorie ne column.categorie}"
                               update=":admTables:categorieForm:admCategorie">
                    <p:graphicImage library="default" name="img/uncheck.png" styleClass="iconCheck" />
                </p:commandLink>
                </ui:repeat>
 
            </p:columns>
 
        </p:dataTable>
    </h:form>
 
</h:body>
</html>
Ma problématique est la suivante.
Lorsqu'un motif est associé à une catégorie, le commandLink "removeButton" est normalement rendered. Evidemment, comme l'ui:repeat parcourt l'ensemble de la liste des catégories associées au motif, autant de commandLink "addButton" sont aussi rendered.
Est-il possible d'exécuter un "break" dans la boucle lorsqu'une association est trouvée ?

En espérant être clair, merci d'avance.