use of org.hibernate.exception.ConstraintViolationException in project Asqatasun by Asqatasun.
the class ContentDAOImpl method saveContentRelationShip.
/**
* This native query is used to avoid multiple select before insert realized
* by hibernate while persisting the content relationship relation.
* @param ssp
*/
@Override
public void saveContentRelationShip(SSP ssp, Set<Long> relatedContentIdSet) {
List<Long> relatedContentIds = findRelatedContentFromSsp(ssp);
Set<Long> newRelatedContentIdSet = new HashSet<>();
for (Long relatedContentId : relatedContentIdSet) {
if (!relatedContentIds.contains(relatedContentId)) {
newRelatedContentIdSet.add(relatedContentId);
}
}
if (!newRelatedContentIdSet.isEmpty()) {
StringBuilder queryValuesBuilder = new StringBuilder();
for (Long relatedContentId : newRelatedContentIdSet) {
queryValuesBuilder.append("(");
queryValuesBuilder.append(ssp.getId());
queryValuesBuilder.append(",");
queryValuesBuilder.append(relatedContentId);
queryValuesBuilder.append(")");
queryValuesBuilder.append(",");
}
queryValuesBuilder.setCharAt(queryValuesBuilder.length() - 1, ';');
Query query = entityManager.createNativeQuery(INSERT_QUERY + queryValuesBuilder.toString());
try {
query.executeUpdate();
// flushAndCloseEntityManager();
} catch (ConstraintViolationException micve) {
LOGGER.warn(micve.getMessage());
} finally {
// flushAndCloseEntityManager();
}
}
}
use of org.hibernate.exception.ConstraintViolationException in project midpoint by Evolveum.
the class ObjectUpdater method modifyObjectAttempt.
/**
* @param externalSession If non-null, this session is used to execute the operation. Note that usual commit/rollback is
* issued even if external session is present. We assume we are the last element of the processing in the session.
*/
public <T extends ObjectType> ModifyObjectResult<T> modifyObjectAttempt(Class<T> type, String oid, Collection<? extends ItemDelta<?, ?>> originalModifications, ModificationPrecondition<T> precondition, RepoModifyOptions originalModifyOptions, int attempt, OperationResult result, SqlRepositoryServiceImpl sqlRepositoryService, boolean noFetchExtensionValueInsertionForbidden, Session externalSession) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException, SerializationRelatedException, PreconditionViolationException {
RepoModifyOptions modifyOptions = adjustExtensionValuesHandling(originalModifyOptions, noFetchExtensionValueInsertionForbidden);
AttemptContext attemptContext = new AttemptContext();
// clone - because some certification and lookup table related methods manipulate this collection and even their constituent deltas
// TODO clone elements only if necessary
Collection<? extends ItemDelta<?, ?>> modifications = CloneUtil.cloneCollectionMembers(originalModifications);
// modifications = new ArrayList<>(modifications);
LOGGER.debug("Modifying object '{}' with oid '{}' (attempt {}) (adjusted options: {})", type.getSimpleName(), oid, attempt, modifyOptions);
LOGGER_PERFORMANCE.debug("> modify object {}, oid={} (attempt {}), modifications={}", type.getSimpleName(), oid, attempt, modifications);
LOGGER.trace("Modifications:\n{}", DebugUtil.debugDumpLazily(modifications));
LOGGER.trace("noFetchExtensionValueInsertionForbidden: {}", noFetchExtensionValueInsertionForbidden);
Session session = externalSession;
OrgClosureManager.Context closureContext = null;
try {
if (session == null) {
session = baseHelper.beginTransaction();
}
closureContext = closureManager.onBeginTransactionModify(session, type, oid, modifications);
Collection<? extends ItemDelta<?, ?>> lookupTableModifications = lookupTableHelper.filterLookupTableModifications(type, modifications);
Collection<? extends ItemDelta<?, ?>> campaignCaseModifications = caseHelper.filterCampaignCaseModifications(type, modifications);
ModifyObjectResult<T> rv;
boolean reindex = RepoModifyOptions.isForceReindex(modifyOptions);
if (!modifications.isEmpty() || reindex) {
// JpegPhoto (RFocusPhoto) is a special kind of entity. First of all, it is lazily loaded, because photos are really big.
// Each RFocusPhoto naturally belongs to one RFocus, so it would be appropriate to set orphanRemoval=true for focus-photo
// association. However, this leads to a strange problem when merging in-memory RFocus object with the database state:
// If in-memory RFocus object has no photo associated (because of lazy loading), then the associated RFocusPhoto is deleted.
//
// To prevent this behavior, we've set orphanRemoval to false. Fortunately, the remove operation on RFocus
// seems to be still cascaded to RFocusPhoto. What we have to implement ourselves, however, is removal of RFocusPhoto
// _without_ removing of RFocus. In order to know whether the photo has to be removed, we have to retrieve
// its value, apply the delta (e.g. if the delta is a DELETE VALUE X, we have to know whether X matches current
// value of the photo), and if the resulting value is empty, we have to manually delete the RFocusPhoto instance.
//
// So the first step is to retrieve the current value of photo - we obviously do this only if the modifications
// deal with the jpegPhoto property.
//
// TODO handling of "externally stored" items (focus.jpegPhoto, task.result, lookupTable.row, ...)
// is a kind of ugly magic. It needs to be reviewed and fixed.
GetOperationOptionsBuilder optionsBuilder = schemaService.getOperationOptionsBuilder();
boolean containsFocusPhotoModification = FocusType.class.isAssignableFrom(type) && containsPhotoModification(modifications);
if (containsFocusPhotoModification) {
LOGGER.trace("Setting 'retrieve' option on jpegPhoto for object fetching because containsFocusPhotoModification=true");
optionsBuilder = optionsBuilder.item(FocusType.F_JPEG_PHOTO).retrieve();
}
if (reindex) {
LOGGER.trace("Setting 'raw' option for object fetching because reindex is being applied");
optionsBuilder = optionsBuilder.root().raw();
if (TaskType.class.isAssignableFrom(type) || ShadowType.class.isAssignableFrom(type)) {
// Certification campaigns and lookup tables treat their externally stored items (cases, rows)
// in a different way that collides with the use of "retrieve" option. TODO resolve this!
LOGGER.trace("Setting 'retrieve' option for object fetching because reindex is being applied");
optionsBuilder = optionsBuilder.root().retrieve();
} else {
LOGGER.trace("Setting 'retrieve' option for c:extension for object fetching because reindex is being applied");
// index-only items can be also here
optionsBuilder = optionsBuilder.item(ObjectType.F_EXTENSION).retrieve();
}
}
// get object
PrismObject<T> prismObject = objectRetriever.getObjectInternal(session, type, oid, optionsBuilder.build(), true);
if (precondition != null && !precondition.holds(prismObject)) {
throw new PreconditionViolationException("Modification precondition does not hold for " + prismObject);
}
sqlRepositoryService.invokeConflictWatchers(w -> w.beforeModifyObject(prismObject));
// apply diff
LOGGER.trace("OBJECT before:\n{}", prismObject.debugDumpLazily());
PrismObject<T> originalObject = prismObject.clone();
boolean shouldPhotoBeRemoved;
if (reindex) {
// old implementation start
ItemDeltaCollectionsUtil.applyTo(modifications, prismObject);
LOGGER.trace("OBJECT after:\n{}", prismObject.debugDumpLazily());
// Continuing the photo treatment: should we remove the (now obsolete) focus photo?
// We have to test prismObject at this place, because updateFullObject (below) removes photo property from the prismObject.
shouldPhotoBeRemoved = containsFocusPhotoModification && ((FocusType) prismObject.asObjectable()).getJpegPhoto() == null;
// merge and update object
LOGGER.trace("Translating JAXB to data type.");
ObjectTypeUtil.normalizeAllRelations(prismObject, relationRegistry);
PrismIdentifierGenerator idGenerator = new PrismIdentifierGenerator(PrismIdentifierGenerator.Operation.MODIFY);
RObject rObject = createDataObjectFromJAXB(prismObject, idGenerator);
rObject.setVersion(rObject.getVersion() + 1);
updateFullObject(rObject, prismObject);
LOGGER.trace("Starting merge.");
session.merge(rObject);
// old implementation end
} else {
// new implementation start
RObject rObject = objectDeltaUpdater.modifyObject(type, oid, modifications, prismObject, modifyOptions, session, attemptContext);
LOGGER.trace("OBJECT after:\n{}", prismObject.debugDumpLazily());
// Continuing the photo treatment: should we remove the (now obsolete) focus photo?
// We have to test prismObject at this place, because updateFullObject (below) removes photo property from the prismObject.
shouldPhotoBeRemoved = containsFocusPhotoModification && ((FocusType) prismObject.asObjectable()).getJpegPhoto() == null;
updateFullObject(rObject, prismObject);
LOGGER.trace("Starting save.");
session.save(rObject);
LOGGER.trace("Save finished.");
// new implementation end
}
if (closureManager.isEnabled()) {
closureManager.updateOrgClosure(originalObject, modifications, session, oid, type, OrgClosureManager.Operation.MODIFY, closureContext);
}
// we have to remove the photo manually.
if (shouldPhotoBeRemoved) {
Query<?> query = session.createQuery("delete RFocusPhoto where ownerOid = :oid");
query.setParameter("oid", prismObject.getOid());
query.executeUpdate();
LOGGER.trace("Focus photo for {} was deleted", prismObject.getOid());
}
rv = new ModifyObjectResult<>(originalObject, prismObject, originalModifications);
} else {
rv = new ModifyObjectResult<>(originalModifications);
}
if (LookupTableType.class.isAssignableFrom(type)) {
lookupTableHelper.updateLookupTableData(session, oid, lookupTableModifications);
}
if (AccessCertificationCampaignType.class.isAssignableFrom(type)) {
caseHelper.updateCampaignCases(session, oid, campaignCaseModifications, modifyOptions);
}
LOGGER.trace("Before commit...");
session.getTransaction().commit();
LOGGER.trace("Committed! (at attempt {})", attempt);
return rv;
} catch (ObjectNotFoundException | SchemaException ex) {
baseHelper.rollbackTransaction(session, ex, result, true);
throw ex;
} catch (PersistenceException ex) {
ConstraintViolationException constEx = ExceptionUtil.findCause(ex, ConstraintViolationException.class);
if (constEx != null) {
handleConstraintViolationExceptionSpecialCases(constEx, session, attemptContext, result);
baseHelper.rollbackTransaction(session, constEx, result, true);
LOGGER.debug("Constraint violation occurred (will be rethrown as ObjectAlreadyExistsException).", constEx);
// todo improve (we support only 5 DB, so we should probably do some hacking in here)
throw new ObjectAlreadyExistsException(constEx);
} else {
baseHelper.handleGeneralException(ex, session, result);
throw new AssertionError("Shouldn't get here");
}
} catch (DtoTranslationException | RuntimeException ex) {
baseHelper.handleGeneralException(ex, session, result);
throw new AssertionError("Shouldn't get here");
} finally {
cleanupClosureAndSessionAndResult(closureContext, session, result);
LOGGER.trace("Session cleaned up.");
}
}
use of org.hibernate.exception.ConstraintViolationException in project CzechIdMng by bcvsolutions.
the class ExceptionControllerAdvice method handle.
@ExceptionHandler(DataIntegrityViolationException.class)
public ResponseEntity<ResultModels> handle(DataIntegrityViolationException ex) {
ErrorModel errorModel = null;
//
if (ex.getCause() != null && ex.getCause() instanceof ConstraintViolationException) {
ConstraintViolationException constraintEx = (ConstraintViolationException) ex.getCause();
// TODO: registrable constraint error codes
if (constraintEx.getConstraintName() != null && constraintEx.getConstraintName().contains("name")) {
errorModel = new DefaultErrorModel(CoreResultCode.NAME_CONFLICT, ImmutableMap.of("name", constraintEx.getConstraintName()));
} else if (constraintEx.getConstraintName() != null && constraintEx.getConstraintName().contains("code")) {
errorModel = new DefaultErrorModel(CoreResultCode.CODE_CONFLICT, ImmutableMap.of("name", constraintEx.getConstraintName()));
} else if (constraintEx.getConstraintName() == null) {
errorModel = new DefaultErrorModel(CoreResultCode.CONFLICT, ImmutableMap.of("name", "..."));
} else {
errorModel = new DefaultErrorModel(CoreResultCode.CONFLICT, ImmutableMap.of("name", StringUtils.trimToEmpty(constraintEx.getConstraintName())));
}
} else {
errorModel = new DefaultErrorModel(CoreResultCode.CONFLICT, ex.getMostSpecificCause().getMessage());
}
LOG.error("[" + errorModel.getId() + "] ", ex);
return new ResponseEntity<>(new ResultModels(errorModel), new HttpHeaders(), errorModel.getStatus());
}
use of org.hibernate.exception.ConstraintViolationException in project hibernate-orm by hibernate.
the class SQLExceptionConversionTest method testIntegrityViolation.
@Test
@SkipForDialect(value = { MySQLMyISAMDialect.class, AbstractHANADialect.class }, comment = "MySQL (MyISAM) / Hana do not support FK violation checking")
public void testIntegrityViolation() throws Exception {
final Session session = openSession();
session.beginTransaction();
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
// Attempt to insert some bad values into the T_MEMBERSHIP table that should
// result in a constraint violation
PreparedStatement ps = null;
try {
ps = ((SessionImplementor) session).getJdbcCoordinator().getStatementPreparer().prepareStatement("INSERT INTO T_MEMBERSHIP (user_id, group_id) VALUES (?, ?)");
// Non-existent user_id
ps.setLong(1, 52134241);
// Non-existent group_id
ps.setLong(2, 5342);
((SessionImplementor) session).getJdbcCoordinator().getResultSetReturn().executeUpdate(ps);
fail("INSERT should have failed");
} catch (ConstraintViolationException ignore) {
// expected outcome
} finally {
releaseStatement(session, ps);
}
}
});
session.getTransaction().rollback();
session.close();
}
use of org.hibernate.exception.ConstraintViolationException in project hibernate-orm by hibernate.
the class BulkManipulationTest method testManyToManyBulkDeleteMultiTable.
@Test
@TestForIssue(jiraKey = "HHH-1917")
public void testManyToManyBulkDeleteMultiTable() {
Session s = openSession();
Transaction t = s.beginTransaction();
Human friend = new Human();
friend.setName(new Name("Bob", 'B', "Bobbert"));
s.save(friend);
Human brett = new Human();
brett.setName(new Name("Brett", 'E', "Meyer"));
brett.setFriends(new ArrayList());
brett.getFriends().add(friend);
s.save(brett);
s.flush();
try {
// multitable (joined subclass)
s.createQuery("delete from Human").executeUpdate();
assertEquals(s.createQuery("from Human").list().size(), 0);
} catch (ConstraintViolationException cve) {
fail("The join table was not cleared prior to the bulk delete.");
} finally {
t.rollback();
s.close();
}
}
Aggregations