p:treeTable与TreeNode的rowKey属性含义及相关技术问题咨询
Let’s walk through your questions one by one—this is a notoriously under-documented area of PrimeFaces, so it’s totally normal to hit these snags!
Question 1: Why does p:dataTable have a rowKey property, but p:treeTable doesn’t (yet TreeNode does)?
The core difference here is the data structure each component is built for:
p:dataTableworks with flat, non-nested datasets. The component-levelrowKeyacts as a global identifier rule for every row in the flat list.p:treeTablerelies on a nested tree structure ofTreeNodeinstances. Since each node is a discrete entity in the tree, the unique identifier (rowKey) is attached directly to individualTreeNodes instead of being defined at the component level. This makes sense because each node’s identity is tied to its position and data in the hierarchy, not a flat list rule.
Question 2: Why does UITree.rowKey serve both as a JSF value binding and the key for the comma-separated selection list?
UITree is the underlying UI component that powers p:treeTable, and its rowKey has a dual purpose tied to how PrimeFaces manages tree state and interactions:
- For JSF value binding: It tracks the current node being processed during rendering or server-side traversal (like when iterating over the tree to render nodes).
- For selection handling: When you select nodes in the frontend, PrimeFaces collects the
rowKeyof each selected node, formats them into a comma-separated string, and sends that back to the server. TheTreeRenderer.decodeSelectionmethod uses this string to look up nodes by theirrowKeyvalues.
This reuse isn’t a quirk—it’s a deliberate design choice to keep node identification consistent across both component rendering and user interaction handling.
Question 3: Why does setting TreeNode.rowKey to a unique hashCode cause an ArrayIndexOutOfBoundsException?
This is a critical gotcha: TreeNode.rowKey is not meant to be an arbitrary unique value like a hashCode. PrimeFaces expects this property to represent the node’s hierarchical path in the tree (e.g., "0.1.2" for the 3rd child of the 2nd child of the root node).
When you set it to a hashCode (which can be negative, like -307459552 in your error), the UITree.findTreeNode method tries to split the rowKey into numeric segments and use those as array indices to traverse the tree. A negative index will immediately throw an ArrayIndexOutOfBoundsException because ArrayList doesn’t support negative indices.
To fix this, set rowKey to a path-based string that reflects the node’s position in the tree, or use a unique positive identifier that PrimeFaces can parse as valid index segments (though path-based is the intended use case).
Question 4: Does the SelectableDataModel documentation apply to TreeNode.rowKey?
No, it doesn’t. SelectableDataModel is designed specifically for flat datasets used by p:dataTable—it lets you define custom logic for retrieving row keys from your data objects.
For p:treeTable, the equivalent is org.primefaces.model.TreeSelectableModel (if you need to customize how selected nodes are handled), but in most cases, you’ll just rely on the rowKey property of TreeNode to manage node identification for selection. The SelectableDataModel rules don’t translate to the nested tree structure of TreeNodes.
内容的提问来源于stack exchange,提问作者Kalle Richter

