Hi,
dynamically build by code.
All my tables are build this way and all works great..
EDT that where not in a4J: region generated mentioned issue.
Detailed Example
 private HtmlExtendedDataTable richTable;
 // Get Table component.
 public HtmlExtendedDataTable getRichTable() {
 LogUtil.log(this.getClass(), richTable);
 if (richTable == null) {
 richTable = new HtmlExtendedDataTable();
 richTable.setSortMode("single");
 richTable.setSelectionMode("multi");
 richTable.setNoDataLabel(MessageUtil.getMessage("liste_empty"));
 richTable.getChildren().addAll(this.getTableRichColumns());
 }
 return richTable;
 }
 public void setRichTable(HtmlExtendedDataTable richTable) {
 this.richTable = richTable;
 }
and 
 @Override
 protected List<HtmlColumn> getTableRichColumns() {
 // Get columns.
 //Loop through all visible headers
 headers = GridUtil.getHeaders(groupName, gridName, this.getObjectClass());
 GridColumn gridColumn = null;
 HtmlColumn column = null;
 String header = null;
 Field fld = null;
 String fldName = null;
 UIComponent content = null;
 List<HtmlColumn> columns = new ArrayList<HtmlColumn>(headers.size());
 //TableState
 LinkedHashMap<String,String> tableStateVisiblity = new LinkedHashMap<String, String>(headers.size()+1);
 LinkedHashMap<String,String> tableStateSize = new LinkedHashMap<String, String>(headers.size()+1);
 LinkedHashMap<String,String> tableStateOrder = new LinkedHashMap<String, String>(headers.size()+1);
 //Add Style col : necessary due to Currency Management
 if (styled){
 column = ComponentUtil.getRichColumn(gridName + "StyleCol", "style","#{row.lineStyle};padding:1px 2px;","30");
 content = ComponentUtil.getOutputText(gridName + "Style", true, "#{msgs.grid_style}");
 column.getChildren().add(content);
 columns.add(column);
 //TableState
 tableStateVisiblity.put(gridName + "StyleCol", "1");
 tableStateSize.put(gridName + "StyleCol", "30");
 tableStateOrder.put(gridName + "StyleCol", null);
 }
 Iterator<String> iter = headers.keySet().iterator();
 String genesysName = null;
 String genesysNameXXX = null;
 for (int i = 0; i < headers.size(); i++) {
 content = null;
 try {
 genesysName = iter.next();
 gridColumn = (GridColumn) headers.get(genesysName);
 genesysNameXXX = gridColumn.getGenesysNameXXX();
 //Fld = @Column field if GridColumn.isJoin()=false
 //OR Fld = @JoinColumn field GridColumn.isJoin()=true
 fld = gridColumn.getEntityField();
 LogUtil.log(this.getClass(), "VISIBLE Field = " + fld.getName() + " with Header = " + gridColumn.getHeader());
 header = gridColumn.getHeader();
 fldName = fld.getName();
 String reRender = gridColumn.getReRender();
 String colStyle = "padding:2px 2px;margin:0px;";
 column = ComponentUtil.getRichColumn(genesysNameXXX + "Col", header, fldName, true, null, null, "#{row." + fldName + "}");
 boolean numeric = ClassUtil.isNumeric(fld);
 content = ComponentUtil.getInputText(fldName, "#{row." + fldName + "}", null, gridColumn.getNbCar(), lockedOrValidatedDependent,numeric, gridColumn.isReRenderCol(),gridColumn.getReRender());
 if (numeric) {
 colStyle += "text-align:right;";
 }
 if (content != null) {
 column.getChildren().add(content);
 }
 column.setWidth(Integer.toString(gridColumn.getWidth() + 15) );
 column.setStyle(colStyle);
 column.setVisible(gridColumn.isVisible());
 columns.add(column);
 //TableState
 String visibleStr = gridColumn.isVisible()?"1":"0";
 tableStateVisiblity.put(genesysNameXXX + "Col", visibleStr);
 tableStateSize.put(genesysNameXXX + "Col", Integer.toString(gridColumn.getWidth() + 15));
 tableStateOrder.put(genesysNameXXX + "Col", null);
 } catch (Exception ex) {
 LogUtil.error(this.getClass(), "=====>!!!!!!!!!!!!! ERROR ON COLUMN" + genesysName);
 }
 }
 return columns;
 }
and 
 public static HtmlColumn getRichColumn(String id,
 String header,
 String fieldName,
 boolean sortable,
 String sortBy,
 String sortOrder,
 String filterBy) {
 // Get table column.
 HtmlColumn col = new HtmlColumn();
 col.setId(id); // Set id.
 String headerLabel = header == null ? " " : header;
 col.setLabel(headerLabel);
// if (header != null) {
 HtmlOutputText headerFacet = new HtmlOutputText();
 headerFacet.setValue(headerLabel);
 col.getFacets().put("header", headerFacet);
// }
 col.setSortable(sortable);
 if (sortable) {
 if (sortBy != null) {
 ComponentUtil.setValueExpression(col, "sortBy", sortBy);
 } else {
 ComponentUtil.setValueExpression(col, "sortBy", "#{row." + fieldName + "}");
 }
 if (sortOrder != null) {
 col.setSortOrder(Ordering.valueOf(sortOrder));
 }
 }
 if (filterBy != null) {
 ComponentUtil.setValueExpression(col, "filterBy", filterBy);
 col.setFilterEvent("onchange");
 }
 return col;
 }