@Override
    public List<PublishedItem> getPublishedItems(LeafNode node, int maxRows) {
    	Connection con = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        int max = MAX_ROWS_FETCH;
        int maxPublished = node.getMaxPublishedItems();

        // Limit the max rows until a solution is in place with Result Set Management
        if (maxRows != -1)
        	max = maxPublished == -1 ? Math.min(maxRows, MAX_ROWS_FETCH) :  Math.min(maxRows, maxPublished);
        else if (maxPublished != -1)
        	max = Math.min(MAX_ROWS_FETCH, maxPublished);

		java.util.LinkedList<PublishedItem> results = new java.util.LinkedList<>();
		boolean descending = JiveGlobals.getBooleanProperty("xmpp.pubsub.order.descending", false);

		try
		{
            con = DbConnectionManager.getConnection();
            // Get published items of the specified node
            if (DbConnectionManager.getDatabaseType().equals(DbConnectionManager.DatabaseType.sqlserver)) {
                pstmt = con.prepareStatement(LOAD_LAST_ITEMS_TOP);
            } else if (DbConnectionManager.getDatabaseType().equals(DbConnectionManager.DatabaseType.oracle)) {
                pstmt = con.prepareStatement(LOAD_LAST_ITEMS_FETCHFIRST);
            } else {
                pstmt = con.prepareStatement(LOAD_LAST_ITEMS_LIMIT);
            }
            pstmt.setMaxRows(max);
            int paramIndex = 0;
            if (DbConnectionManager.getDatabaseType().equals(DbConnectionManager.DatabaseType.sqlserver)){
                pstmt.setLong(++paramIndex, max);
            }
            pstmt.setString(++paramIndex, node.getUniqueIdentifier().getServiceIdentifier().getServiceId());
            pstmt.setString(++paramIndex, encodeNodeID(node.getNodeID()));
            if (!DbConnectionManager.getDatabaseType().equals(DbConnectionManager.DatabaseType.sqlserver)){
                pstmt.setLong(++paramIndex, max);
            }
            rs = pstmt.executeQuery();

            // Rebuild loaded published items
            while(rs.next()) {
                String itemID = rs.getString(1);
                JID publisher = new JID(rs.getString(2));
                Date creationDate = new Date(Long.parseLong(rs.getString(3).trim()));
                // Create the item
                PublishedItem item = new PublishedItem(node, publisher, itemID, creationDate);
                // Add the extra fields to the published item
                if (rs.getString(4) != null) {
                	item.setPayloadXML(rs.getString(4));
                }
                // Add the published item to the node
				if (descending) {
                    results.add(item);
                } else {
                    results.addFirst(item);
                }
            }
        }
        catch (Exception sqle) {
            log.error("An exception occurred while trying to load the last {} published item(s) from node {}", maxRows, node.getUniqueIdentifier(), sqle);
        }
        finally {
            DbConnectionManager.closeConnection(rs, pstmt, con);
        }

        return results;
    }
Writes large changesets to the database, using batches and transactions when
available.

The 'delete' list takes precedence over the 'add' list: when an item exists
on both lists, it is removed (and not re-added) to the database.

To prevent duplicates to exist in the database, this method will attempt to
remove all items to-be-added from the database, before re-adding them.

Note that multiple attempts to write items to the DB are made:
1) insert all pending items in a single batch
2) if the batch insert fails, retry by inserting each item separately

@param addList A list of items to be added to the database.
@param delList A list of items to be removed from the database.
xmppserver/src/main/java/org/jivesoftware/openfire/pubsub/DefaultPubSubPersistenceProvider.java