Skip to content

Commit

Permalink
DURACOM-225 porting of the uuid iterator implementation from dspace-c…
Browse files Browse the repository at this point in the history
…ris to retrie just the uuid from the database in the initial query
  • Loading branch information
abollini committed Jan 20, 2024
1 parent 4dd3120 commit 729e389
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
Expand All @@ -26,6 +27,7 @@
import org.dspace.core.AbstractHibernateDSODAO;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.UUIDIterator;

/**
* Hibernate implementation of the Database Access Object interface class for the Bitstream object.
Expand Down Expand Up @@ -76,48 +78,53 @@ public List<Bitstream> findBitstreamsWithNoRecentChecksum(Context context) throw

@Override
public Iterator<Bitstream> findByCommunity(Context context, Community community) throws SQLException {
Query query = createQuery(context, "select b from Bitstream b " +
Query query = createQuery(context, "select b.id from Bitstream b " +
"join b.bundles bitBundles " +
"join bitBundles.items item " +
"join item.collections itemColl " +
"join itemColl.communities community " +
"WHERE :community IN community");

query.setParameter("community", community);

return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Bitstream>(context, uuids, Bitstream.class, this);
}

@Override
public Iterator<Bitstream> findByCollection(Context context, Collection collection) throws SQLException {
Query query = createQuery(context, "select b from Bitstream b " +
Query query = createQuery(context, "select b.id from Bitstream b " +
"join b.bundles bitBundles " +
"join bitBundles.items item " +
"join item.collections c " +
"WHERE :collection IN c");

query.setParameter("collection", collection);

return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Bitstream>(context, uuids, Bitstream.class, this);
}

@Override
public Iterator<Bitstream> findByItem(Context context, Item item) throws SQLException {
Query query = createQuery(context, "select b from Bitstream b " +
Query query = createQuery(context, "select b.id from Bitstream b " +
"join b.bundles bitBundles " +
"join bitBundles.items item " +
"WHERE :item IN item");

query.setParameter("item", item);

return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Bitstream>(context, uuids, Bitstream.class, this);
}

@Override
public Iterator<Bitstream> findByStoreNumber(Context context, Integer storeNumber) throws SQLException {
Query query = createQuery(context, "select b from Bitstream b where b.storeNumber = :storeNumber");
Query query = createQuery(context, "select b.id from Bitstream b where b.storeNumber = :storeNumber");
query.setParameter("storeNumber", storeNumber);
return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Bitstream>(context, uuids, Bitstream.class, this);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.dspace.content.dao.ItemDAO;
import org.dspace.core.AbstractHibernateDSODAO;
import org.dspace.core.Context;
import org.dspace.core.UUIDIterator;
import org.dspace.eperson.EPerson;
import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
Expand Down Expand Up @@ -55,28 +56,34 @@ protected ItemDAOImpl() {

@Override
public Iterator<Item> findAll(Context context, boolean archived) throws SQLException {
Query query = createQuery(context, "FROM Item WHERE inArchive=:in_archive ORDER BY id");
Query query = createQuery(context, "SELECT i.id FROM Item i WHERE inArchive=:in_archive ORDER BY id");
query.setParameter("in_archive", archived);
return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Item>(context, uuids, Item.class, this);
}

@Override
public Iterator<Item> findAll(Context context, boolean archived, int limit, int offset) throws SQLException {
Query query = createQuery(context, "FROM Item WHERE inArchive=:in_archive ORDER BY id");
Query query = createQuery(context, "SELECT i.id FROM Item i WHERE inArchive=:in_archive ORDER BY id");
query.setParameter("in_archive", archived);
query.setFirstResult(offset);
query.setMaxResults(limit);
return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Item>(context, uuids, Item.class, this);
}


@Override
public Iterator<Item> findAll(Context context, boolean archived, boolean withdrawn) throws SQLException {
Query query = createQuery(context,
"FROM Item WHERE inArchive=:in_archive or withdrawn=:withdrawn ORDER BY id");
"SELECT i.id FROM Item i WHERE inArchive=:in_archive or withdrawn=:withdrawn ORDER BY id");
query.setParameter("in_archive", archived);
query.setParameter("withdrawn", withdrawn);
return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Item>(context, uuids, Item.class, this);
}

@Override
Expand All @@ -85,20 +92,22 @@ public Iterator<Item> findAllRegularItems(Context context) throws SQLException {
// It does not include workspace, workflow or template items.
Query query = createQuery(
context,
"SELECT i FROM Item as i " +
"SELECT i.id FROM Item as i " +
"LEFT JOIN Version as v ON i = v.item " +
"WHERE i.inArchive=true or i.withdrawn=true or (i.inArchive=false and v.id IS NOT NULL) " +
"ORDER BY i.id"
);
return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Item>(context, uuids, Item.class, this);
}

@Override
public Iterator<Item> findAll(Context context, boolean archived,
boolean withdrawn, boolean discoverable, Date lastModified)
throws SQLException {
StringBuilder queryStr = new StringBuilder();
queryStr.append("SELECT i FROM Item i");
queryStr.append("SELECT i.id FROM Item i");
queryStr.append(" WHERE (inArchive = :in_archive OR withdrawn = :withdrawn)");
queryStr.append(" AND discoverable = :discoverable");

Expand All @@ -114,16 +123,20 @@ public Iterator<Item> findAll(Context context, boolean archived,
if (lastModified != null) {
query.setParameter("last_modified", lastModified, TemporalType.TIMESTAMP);
}
return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Item>(context, uuids, Item.class, this);
}

@Override
public Iterator<Item> findBySubmitter(Context context, EPerson eperson) throws SQLException {
Query query = createQuery(context,
"FROM Item WHERE inArchive=:in_archive and submitter=:submitter ORDER BY id");
"SELECT i.id FROM Item i WHERE inArchive=:in_archive and submitter=:submitter ORDER BY id");
query.setParameter("in_archive", true);
query.setParameter("submitter", eperson);
return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Item>(context, uuids, Item.class, this);
}

@Override
Expand All @@ -132,16 +145,18 @@ public Iterator<Item> findBySubmitter(Context context, EPerson eperson, boolean
if (!retrieveAllItems) {
return findBySubmitter(context, eperson);
}
Query query = createQuery(context, "FROM Item WHERE submitter=:submitter ORDER BY id");
Query query = createQuery(context, "SELECT i.id FROM Item i WHERE submitter=:submitter ORDER BY id");
query.setParameter("submitter", eperson);
return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Item>(context, uuids, Item.class, this);
}

@Override
public Iterator<Item> findBySubmitter(Context context, EPerson eperson, MetadataField metadataField, int limit)
throws SQLException {
StringBuilder query = new StringBuilder();
query.append("SELECT item FROM Item as item ");
query.append("SELECT item.id FROM Item as item ");
addMetadataLeftJoin(query, Item.class.getSimpleName().toLowerCase(), Collections.singletonList(metadataField));
query.append(" WHERE item.inArchive = :in_archive");
query.append(" AND item.submitter =:submitter");
Expand All @@ -153,13 +168,15 @@ public Iterator<Item> findBySubmitter(Context context, EPerson eperson, Metadata
hibernateQuery.setParameter("in_archive", true);
hibernateQuery.setParameter("submitter", eperson);
hibernateQuery.setMaxResults(limit);
return iterate(hibernateQuery);
@SuppressWarnings("unchecked")
List<UUID> uuids = hibernateQuery.getResultList();
return new UUIDIterator<Item>(context, uuids, Item.class, this);
}

@Override
public Iterator<Item> findByMetadataField(Context context, MetadataField metadataField, String value,
boolean inArchive) throws SQLException {
String hqlQueryString = "SELECT item FROM Item as item join item.metadata metadatavalue " +
String hqlQueryString = "SELECT item.id FROM Item as item join item.metadata metadatavalue " +
"WHERE item.inArchive=:in_archive AND metadatavalue.metadataField = :metadata_field";
if (value != null) {
hqlQueryString += " AND STR(metadatavalue.value) = :text_value";
Expand All @@ -171,7 +188,9 @@ public Iterator<Item> findByMetadataField(Context context, MetadataField metadat
if (value != null) {
query.setParameter("text_value", value);
}
return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Item>(context, uuids, Item.class, this);
}

enum OP {
Expand Down Expand Up @@ -292,20 +311,22 @@ public Iterator<Item> findByMetadataQuery(Context context, List<List<MetadataFie
public Iterator<Item> findByAuthorityValue(Context context, MetadataField metadataField, String authority,
boolean inArchive) throws SQLException {
Query query = createQuery(context,
"SELECT item FROM Item as item join item.metadata metadatavalue " +
"SELECT item.id FROM Item as item join item.metadata metadatavalue " +
"WHERE item.inArchive=:in_archive AND metadatavalue.metadataField = :metadata_field AND " +
"metadatavalue.authority = :authority ORDER BY item.id");
query.setParameter("in_archive", inArchive);
query.setParameter("metadata_field", metadataField);
query.setParameter("authority", authority);
return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Item>(context, uuids, Item.class, this);
}

@Override
public Iterator<Item> findArchivedByCollection(Context context, Collection collection, Integer limit,
Integer offset) throws SQLException {
Query query = createQuery(context,
"select i from Item i join i.collections c " +
"select i.id from Item i join i.collections c " +
"WHERE :collection IN c AND i.inArchive=:in_archive ORDER BY i.id");
query.setParameter("collection", collection);
query.setParameter("in_archive", true);
Expand All @@ -315,7 +336,9 @@ public Iterator<Item> findArchivedByCollection(Context context, Collection colle
if (limit != null) {
query.setMaxResults(limit);
}
return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Item>(context, uuids, Item.class, this);
}

@Override
Expand Down Expand Up @@ -350,17 +373,18 @@ public int countArchivedByCollectionExcludingOwning(Context context, Collection
@Override
public Iterator<Item> findAllByCollection(Context context, Collection collection) throws SQLException {
Query query = createQuery(context,
"select i from Item i join i.collections c WHERE :collection IN c ORDER BY i.id");
"select i.id from Item i join i.collections c WHERE :collection IN c ORDER BY i.id");
query.setParameter("collection", collection);

return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Item>(context, uuids, Item.class, this);
}

@Override
public Iterator<Item> findAllByCollection(Context context, Collection collection, Integer limit, Integer offset)
throws SQLException {
Query query = createQuery(context,
"select i from Item i join i.collections c WHERE :collection IN c ORDER BY i.id");
"select i.id from Item i join i.collections c WHERE :collection IN c ORDER BY i.id");
query.setParameter("collection", collection);

if (offset != null) {
Expand All @@ -369,8 +393,9 @@ public Iterator<Item> findAllByCollection(Context context, Collection collection
if (limit != null) {
query.setMaxResults(limit);
}

return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Item>(context, uuids, Item.class, this);
}

@Override
Expand Down Expand Up @@ -406,9 +431,11 @@ public int countItems(Context context, List<Collection> collections, boolean inc
public Iterator<Item> findByLastModifiedSince(Context context, Date since)
throws SQLException {
Query query = createQuery(context,
"SELECT i FROM Item i WHERE last_modified > :last_modified ORDER BY id");
"SELECT i.id FROM Item i WHERE last_modified > :last_modified ORDER BY id");
query.setParameter("last_modified", since, TemporalType.TIMESTAMP);
return iterate(query);
@SuppressWarnings("unchecked")
List<UUID> uuids = query.getResultList();
return new UUIDIterator<Item>(context, uuids, Item.class, this);
}

@Override
Expand Down
63 changes: 63 additions & 0 deletions dspace-api/src/main/java/org/dspace/core/UUIDIterator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.core;

import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;

import com.google.common.collect.AbstractIterator;
import org.dspace.content.DSpaceObject;
import org.springframework.beans.factory.annotation.Autowired;

/**
* Iterator implementation which allows to iterate over items and commit while
* iterating. Using an iterator over previous retrieved UUIDs the iterator doesn't
* get invalidated after a commit that would instead close the database ResultSet
*
* @author Andrea Bollini (andrea.bollini at 4science.com)
* @param <T> class type
*/
public class UUIDIterator<T extends DSpaceObject> extends AbstractIterator<T> {
private Class<T> clazz;

private Iterator<UUID> iterator;

@Autowired
private AbstractHibernateDSODAO<T> dao;

private Context ctx;

public UUIDIterator(Context ctx, List<UUID> uuids, Class<T> clazz, AbstractHibernateDSODAO<T> dao)
throws SQLException {
this.ctx = ctx;
this.clazz = clazz;
this.dao = dao;
this.iterator = uuids.iterator();
}

@Override
protected T computeNext() {
try {
if (iterator.hasNext()) {
T item = dao.findByID(ctx, clazz, iterator.next());
if (item != null) {
return item;
} else {
return computeNext();
}
} else {
return endOfData();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}

}

0 comments on commit 729e389

Please sign in to comment.