Well, first, I don't recommend actually returning the raw data as a value to a dataTable.
In order to manage the rendering process, a dataTable needs a corresponding DataModel object as a wrapper (façade). In the case where you simply return a raw array or collection of data,
JSF must construct an anonymous DataModel automatically. Nothing inherently wrong with that, except that the DataModel happens to have some properties that are very useful.
In particular, the getRowData method, which can return the data of a selected row (for example, the row in which you clicked a button or link), and the getRowIndex method, which returns the 0-based index of the selected row.
If you construct your own DataModel object, wrap it around your raw data and return that as the value property, you will have done the same thing that JSF did anyway, but now you have an object that your action methods and AJAX listeners can use to understand context without having to fumble through a bunch of unnatural and awkward circumventions. DataModels are easy to use. Just construct them and make them available via property-set. You don't have to re-wrap the data if the data changes unless you completely replace the data collection object with a new object. Changes to data within a collection don't require re-wrapping it.
Which brings me to the second point. The collection that the dataTable represents must be a
sequential collection. That is, a List, array, or other collection that has a natural order. Yes, you can enumerate any collection, but the order in which the elements of that collection are returned must be precisely defined. In the case of a hash, changing even one element can completely scramble the order of the returned items. It's also worth nothing that the collection must return the exact same sequence multiple times (be idempotent), since JSF may call the value "get" method up to about 6 times for a single page request. And thus, also, you don't want to do any expensive operations such as database access in the data set while its value get method is executing.
And now to the specifics. A HashMap internally is a collection of key/value pairs. So when you enumerate the map, what the enumerator is actually returning on each element is an internal object containing one key, one value, and possibly some overhead (such as a hash collision link). That object doesn't implement a useful toString() method since it's not intended to be used directly. Besides, a dataTable usually has multiple columns, so you need to indicate what data goes in what column.
Oh. And one more thing. You're returning a collection containing multiple sub-collections. A dataTable only maps the primary collection. You'll need to flatten out the model to deal with that.
So here's some possibilities.
First, consider an ordered collection as the basis for your dataTable Model. Secondly, make the model elements be something that JSF can deal with as objects with properties or can convert to an array of Strings. In the case of a Map, what I'd normally do is construct a List or Array containing Map elements as user-defined objects, but here's one alternative:
Hopefully you can translate your getUserLogins method to build the login Record List. That's more work than I can justify for this example.
Note that this code has the very useful property that if your model becomes outdated, you can simply set loginRecordModel to null and a fresh model will be built the next time it's needed. That also handles the initial construction more gracefully than trying to do so in the backing bean constructor (which often doesn't have enough context) or a @PostConstruct method.
And now, finally, the dataTable:
Actually, there's something odd about your datatable elements, but since I don't work regularly with PrimeFaces, I'm not sure exactly how to lay it out.
And finally, since this is the sort of thing where you'd like to be able to expand/collapse and/or highlight rows by the major key (loginId), PrimeFaces does have an easy way to do that, but that, too is beyond the scope of this example.
Incidentally, I cheat. I've defined a set of boilerplate snippets in my
IDE to handle the grunt work of setting up the dataModel and building its payload because I've done it so often.