use of io.requery.PersistenceException in project requery by requery.
the class EntityWriter method updateAssociation.
@SuppressWarnings("unchecked")
private void updateAssociation(Cascade mode, E entity, EntityProxy<E> proxy, Attribute<E, ?> attribute) {
switch(attribute.getCardinality()) {
case ONE_TO_ONE:
S value = (S) proxy.get(attribute, false);
if (value != null) {
Attribute<S, Object> mapped = Attributes.get(attribute.getMappedAttribute());
EntityProxy<S> referred = context.proxyOf(value, true);
referred.set(mapped, entity, PropertyState.MODIFIED);
cascadeWrite(mode, value, referred);
} else if (!stateless) {
throw new PersistenceException("1-1 relationship can only be removed from the owning side");
}
break;
case ONE_TO_MANY:
Object relation = proxy.get(attribute, false);
if (relation instanceof ObservableCollection) {
ObservableCollection<S> collection = (ObservableCollection<S>) relation;
CollectionChanges<?, S> changes = (CollectionChanges<?, S>) collection.observer();
List<S> added = new ArrayList<>(changes.addedElements());
List<S> removed = new ArrayList<>(changes.removedElements());
changes.clear();
for (S element : added) {
updateMappedAssociation(mode, element, attribute, entity);
}
for (S element : removed) {
updateMappedAssociation(Cascade.UPDATE, element, attribute, null);
}
} else if (relation instanceof Iterable) {
Iterable<S> iterable = (Iterable<S>) relation;
for (S added : iterable) {
updateMappedAssociation(mode, added, attribute, entity);
}
} else {
throw new IllegalStateException("unsupported relation type " + relation);
}
break;
case MANY_TO_MANY:
final Class referencedClass = attribute.getReferencedClass();
if (referencedClass == null) {
throw new IllegalStateException("Invalid referenced class in " + attribute);
}
Type<?> referencedType = model.typeOf(referencedClass);
QueryAttribute<S, Object> tKey = null;
QueryAttribute<S, Object> uKey = null;
for (Attribute a : referencedType.getAttributes()) {
Class<?> referenced = a.getReferencedClass();
if (referenced != null) {
if (tKey == null && entityClass.isAssignableFrom(referenced)) {
tKey = Attributes.query(a);
} else if (attribute.getElementClass() != null && attribute.getElementClass().isAssignableFrom(referenced)) {
uKey = Attributes.query(a);
}
}
}
Objects.requireNotNull(tKey);
Objects.requireNotNull(uKey);
Attribute<E, Object> tRef = Attributes.get(tKey.getReferencedAttribute());
Attribute<S, Object> uRef = Attributes.get(uKey.getReferencedAttribute());
CollectionChanges<?, S> changes = null;
relation = proxy.get(attribute, false);
Iterable<S> addedElements = (Iterable<S>) relation;
boolean isObservable = relation instanceof ObservableCollection;
if (relation instanceof ObservableCollection) {
ObservableCollection<S> collection = (ObservableCollection<S>) relation;
changes = (CollectionChanges<?, S>) collection.observer();
if (changes != null) {
addedElements = changes.addedElements();
}
}
for (S added : addedElements) {
S junction = (S) referencedType.getFactory().get();
EntityProxy<S> junctionProxy = context.proxyOf(junction, false);
EntityProxy<S> uProxy = context.proxyOf(added, false);
if (attribute.getCascadeActions().contains(CascadeAction.SAVE)) {
cascadeWrite(mode, added, uProxy);
}
Object tValue = proxy.get(tRef, false);
Object uValue = uProxy.get(uRef, false);
junctionProxy.set(tKey, tValue, PropertyState.MODIFIED);
junctionProxy.set(uKey, uValue, PropertyState.MODIFIED);
Cascade cascade = isObservable && mode == Cascade.UPSERT ? Cascade.UPSERT : Cascade.INSERT;
cascadeWrite(cascade, junction, null);
}
if (changes != null) {
Object keyValue = proxy.get(tRef, false);
for (S removed : changes.removedElements()) {
Object otherValue = context.proxyOf(removed, false).get(uRef);
Class<? extends S> removeType = (Class<? extends S>) referencedType.getClassType();
Supplier<? extends Scalar<Integer>> query = queryable.delete(removeType).where(tKey.equal(keyValue)).and(uKey.equal(otherValue));
int count = query.get().value();
if (count != 1) {
throw new RowCountException(entity.getClass(), 1, count);
}
}
changes.clear();
}
break;
case MANY_TO_ONE:
default:
break;
}
context.read(type.getClassType()).refresh(entity, proxy, attribute);
}
use of io.requery.PersistenceException in project requery by requery.
the class SchemaModifier method executeSql.
private void executeSql(Connection connection, QueryBuilder qb) {
try (Statement statement = connection.createStatement()) {
String sql = qb.toString();
statementListeners.beforeExecuteUpdate(statement, sql, null);
statement.execute(sql);
statementListeners.afterExecuteUpdate(statement, 0);
} catch (SQLException e) {
throw new PersistenceException(e);
}
}
use of io.requery.PersistenceException in project requery by requery.
the class BatchUpdateOperation method evaluate.
@Override
public int[] evaluate(QueryElement<int[]> query) {
int[] result = batchInStatement ? null : new int[length];
try (Connection connection = configuration.getConnection()) {
DefaultOutput generator = new DefaultOutput(configuration, query);
String sql = generator.toSql();
StatementListener listener = configuration.getStatementListener();
try (PreparedStatement statement = prepare(sql, connection)) {
for (int i = 0; i < length; i++) {
E element = elements[i];
parameterBinder.bindParameters(statement, element, null);
if (batchInStatement) {
statement.addBatch();
} else {
listener.beforeExecuteBatchUpdate(statement, sql);
result[i] = statement.executeUpdate();
listener.afterExecuteBatchUpdate(statement, result);
readGeneratedKeys(i, statement);
}
}
if (batchInStatement) {
listener.beforeExecuteBatchUpdate(statement, sql);
result = statement.executeBatch();
listener.afterExecuteBatchUpdate(statement, result);
readGeneratedKeys(0, statement);
}
}
} catch (BatchUpdateException e) {
result = e.getUpdateCounts();
if (result == null) {
throw new PersistenceException(e);
}
} catch (SQLException e) {
throw new PersistenceException(e);
}
return result;
}
use of io.requery.PersistenceException in project requery by requery.
the class EntityWriter method incrementVersion.
private void incrementVersion(EntityProxy<E> proxy) {
if (versionAttribute != null && !hasSystemVersionColumn()) {
Object version = proxy.get(versionAttribute);
Class<?> type = versionAttribute.getClassType();
if (type == Long.class || type == long.class) {
if (version == null) {
version = 1L;
} else {
Long value = (Long) version;
version = value + 1;
}
} else if (type == Integer.class || type == int.class) {
if (version == null) {
version = 1;
} else {
Integer value = (Integer) version;
version = value + 1;
}
} else if (type == Timestamp.class) {
version = new Timestamp(System.currentTimeMillis());
} else {
throw new PersistenceException("Unsupported version type: " + versionAttribute.getClassType());
}
proxy.setObject(versionAttribute, version, PropertyState.MODIFIED);
}
}
use of io.requery.PersistenceException in project requery by requery.
the class EntityReader method refresh.
private E refresh(E entity, EntityProxy<E> proxy, final Set<Attribute<E, ?>> attributes) {
Predicate<Attribute<E, ?>> basicFilter = new Predicate<Attribute<E, ?>>() {
@Override
public boolean test(Attribute<E, ?> value) {
return attributes.contains(value) && (!value.isAssociation() || value.isForeignKey());
}
};
FilteringIterator<Attribute<E, ?>> filterator = new FilteringIterator<>(attributes.iterator(), basicFilter);
if (filterator.hasNext()) {
QueryBuilder qb = new QueryBuilder(context.getQueryBuilderOptions()).keyword(SELECT).commaSeparated(filterator, new QueryBuilder.Appender<Attribute<E, ?>>() {
@Override
public void append(QueryBuilder qb, Attribute<E, ?> value) {
String versionColumn = context.getPlatform().versionColumnDefinition().columnName();
if (value.isVersion() && versionColumn != null) {
qb.append(versionColumn).space().append(AS).space().append(value.getName()).space();
} else {
qb.attribute(value);
}
}
}).keyword(FROM).tableName(type.getName()).keyword(WHERE).appendWhereConditions(type.getKeyAttributes());
String sql = qb.toString();
try (Connection connection = context.getConnection();
PreparedStatement statement = connection.prepareStatement(sql)) {
int index = 1;
for (Attribute<E, ?> attribute : type.getKeyAttributes()) {
Object value = proxy.getKey(attribute);
if (value == null) {
throw new MissingKeyException(proxy);
}
mapping.write((Expression) attribute, statement, index++, value);
}
context.getStatementListener().beforeExecuteQuery(statement, sql, null);
ResultSet results = statement.executeQuery();
context.getStatementListener().afterExecuteQuery(statement);
if (results.next()) {
Attribute[] selection = new Attribute[attributes.size()];
attributes.toArray(selection);
// modify the given entity
if (type.isImmutable()) {
entity = fromBuilder(results, selection);
} else {
entity = fromResult(entity, results, selection);
}
}
} catch (SQLException e) {
throw new PersistenceException(e);
}
}
// refresh associations
for (Attribute<E, ?> attribute : attributes) {
// if it's a foreign key its resolved as part of the basic properties
if (attribute.isAssociation()) {
refreshAssociation(proxy, attribute);
}
}
return entity;
}
Aggregations