com.j256.ormlite.dao.LazyForeignCollection Maven / Gradle / Ivy
package com.j256.ormlite.dao;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.j256.ormlite.field.ForeignCollectionField;
/**
* Collection that is set on a field that as been marked with the {@link ForeignCollectionField} annotation when an
* object is refreshed or queried (i.e. not created). Most of the methods here require a pass through the database.
* Operations such as size() therefore should most likely not be used because of their expense. Chances are you only
* want to use the {@link #iterator()}, {@link #toArray()}, and {@link #toArray(Object[])} methods.
*
*
* WARNING: Most likely for(;;) loops should not be used here since we need to be careful about closing the
* iterator.
*
*
* @author graywatson
*/
public class LazyForeignCollection extends BaseForeignCollection implements ForeignCollection,
Serializable {
private static final long serialVersionUID = -5460708106909626233L;
private transient CloseableIterator lastIterator;
public LazyForeignCollection(Dao dao, Object parent, Object parentId, String columnName, String orderColumn) {
super(dao, parent, parentId, columnName, orderColumn);
}
/**
* The iterator returned from a lazy collection keeps a connection open to the database as it iterates across the
* collection. You will need to call {@link CloseableIterator#close()} or go all the way through the loop to ensure
* that the connection has been closed. You can also call {@link #closeLastIterator()} on the collection itself
* which will close the last iterator returned. See the reentrant warning.
*/
public CloseableIterator iterator() {
return closeableIterator();
}
public CloseableIterator closeableIterator() {
try {
return iteratorThrow();
} catch (SQLException e) {
throw new IllegalStateException("Could not build lazy iterator for " + dao.getDataClass(), e);
}
}
/**
* This is the same as {@link #iterator()} except it throws.
*/
public CloseableIterator iteratorThrow() throws SQLException {
lastIterator = seperateIteratorThrow();
return lastIterator;
}
/**
* Same as {@link #iteratorThrow()} except this doesn't set the last iterator which can be closed with the
* {@link #closeLastIterator()}.
*/
public CloseableIterator seperateIteratorThrow() throws SQLException {
// check state to make sure we have a DAO in case we have a deserialized collection
if (dao == null) {
throw new IllegalStateException(
"Internal DAO object is null. Lazy collections cannot be used if they have been deserialized.");
} else {
return dao.iterator(getPreparedQuery());
}
}
public CloseableWrappedIterable getWrappedIterable() {
return new CloseableWrappedIterableImpl(new CloseableIterable() {
public CloseableIterator iterator() {
return closeableIterator();
}
public CloseableIterator closeableIterator() {
try {
return LazyForeignCollection.this.seperateIteratorThrow();
} catch (Exception e) {
throw new IllegalStateException("Could not build lazy iterator for " + dao.getDataClass(), e);
}
}
});
}
public void closeLastIterator() throws SQLException {
if (lastIterator != null) {
lastIterator.close();
lastIterator = null;
}
}
public boolean isEager() {
return false;
}
public int size() {
CloseableIterator iterator = iterator();
try {
int sizeC;
for (sizeC = 0; iterator.hasNext(); sizeC++) {
// move to next without constructing the object
iterator.moveToNext();
}
return sizeC;
} finally {
try {
iterator.close();
} catch (SQLException e) {
// ignored
}
}
}
public boolean isEmpty() {
CloseableIterator iterator = iterator();
try {
return !iterator.hasNext();
} finally {
try {
iterator.close();
} catch (SQLException e) {
// ignored
}
}
}
public boolean contains(Object obj) {
CloseableIterator iterator = iterator();
try {
while (iterator.hasNext()) {
if (iterator.next().equals(obj)) {
return true;
}
}
return false;
} finally {
try {
iterator.close();
} catch (SQLException e) {
// ignored
}
}
}
public boolean containsAll(Collection collection) {
Set