Add explicit transactional semantics to the deleteEntity method because of problems with Neo4J support.
This commit is contained in:
@@ -1,37 +0,0 @@
|
||||
package org.springframework.data.rest.repository;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.Resources;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
public class PageableResources<T> extends Resources<T> {
|
||||
|
||||
private Pageable page;
|
||||
|
||||
protected PageableResources() {
|
||||
super();
|
||||
}
|
||||
|
||||
public PageableResources(Iterable<T> content, Pageable page, Link... links) {
|
||||
super(content, links);
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
public PageableResources(Iterable<T> content, Pageable page, Iterable<Link> links) {
|
||||
super(content, links);
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
public Pageable getPage() {
|
||||
return page;
|
||||
}
|
||||
|
||||
public PageableResources<T> setPage(Pageable page) {
|
||||
this.page = page;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.springframework.data.rest.repository.invoke;
|
||||
|
||||
import static org.springframework.data.rest.repository.support.ResourceMappingUtils.getResourceMapping;
|
||||
import static org.springframework.util.ReflectionUtils.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
@@ -13,6 +14,8 @@ import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
import org.springframework.data.repository.core.RepositoryInformation;
|
||||
import org.springframework.data.rest.config.RepositoryRestConfiguration;
|
||||
import org.springframework.data.rest.config.ResourceMapping;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
@@ -38,14 +41,14 @@ public class RepositoryMethodInvoker implements PagingAndSortingRepository<Objec
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public RepositoryMethodInvoker(Object repository,
|
||||
RepositoryInformation repoInfo,
|
||||
final PersistentEntity persistentEntity) {
|
||||
RepositoryRestConfiguration config) {
|
||||
this.repository = repository;
|
||||
Class<?> repoType = repoInfo.getRepositoryInterface();
|
||||
|
||||
doWithMethods(repoType, new MethodCallback() {
|
||||
@Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
|
||||
String name = method.getName();
|
||||
int cardinality = method.getParameterTypes().length;
|
||||
int cardinality = method.getParameterTypes().length;
|
||||
Class<?> paramType = (cardinality == 1 ? method.getParameterTypes()[0] : null);
|
||||
boolean someMethod = (null != paramType && Iterable.class.isAssignableFrom(paramType));
|
||||
boolean byIdMethod = (null != paramType && paramType == Serializable.class);
|
||||
|
||||
@@ -49,6 +49,7 @@ public class PersistentEntityToJsonSchemaConverter
|
||||
return (Class.class.isAssignableFrom(sourceType.getType()) && JsonSchema.class.isAssignableFrom(targetType.getType()));
|
||||
}
|
||||
|
||||
|
||||
@Override public Set<ConvertiblePair> getConvertibleTypes() {
|
||||
return convertiblePairs;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@@ -53,6 +54,8 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.http.converter.HttpMessageNotWritableException;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@@ -61,7 +64,8 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
public class AbstractRepositoryRestController implements ApplicationContextAware {
|
||||
public class AbstractRepositoryRestController implements ApplicationContextAware,
|
||||
InitializingBean {
|
||||
|
||||
static final Resource<?> EMPTY_RESOURCE = new Resource<Object>(Collections.emptyList());
|
||||
static final Resources<Resource<?>> EMPTY_RESOURCES = new Resources<Resource<?>>(Collections.<Resource<?>>emptyList());
|
||||
@@ -77,6 +81,9 @@ public class AbstractRepositoryRestController implements ApplicationContextAware
|
||||
protected ApplicationContext applicationContext;
|
||||
@Autowired(required = false)
|
||||
protected ValidationExceptionHandler handler;
|
||||
@Autowired(required = false)
|
||||
protected PlatformTransactionManager txMgr;
|
||||
protected TransactionTemplate txTmpl;
|
||||
|
||||
@Autowired
|
||||
public AbstractRepositoryRestController(Repositories repositories,
|
||||
@@ -96,6 +103,13 @@ public class AbstractRepositoryRestController implements ApplicationContextAware
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override public void afterPropertiesSet() throws Exception {
|
||||
if(null != txMgr) {
|
||||
txTmpl = new TransactionTemplate(txMgr);
|
||||
txTmpl.afterPropertiesSet();
|
||||
}
|
||||
}
|
||||
|
||||
@ExceptionHandler({
|
||||
NullPointerException.class
|
||||
})
|
||||
|
||||
@@ -39,6 +39,8 @@ import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@@ -311,32 +313,41 @@ public class RepositoryEntityController extends AbstractRepositoryRestController
|
||||
method = RequestMethod.DELETE
|
||||
)
|
||||
@ResponseBody
|
||||
public ResponseEntity<?> deleteEntity(RepositoryRestRequest repoRequest,
|
||||
@PathVariable String id)
|
||||
public ResponseEntity<?> deleteEntity(final RepositoryRestRequest repoRequest,
|
||||
@PathVariable final String id)
|
||||
throws ResourceNotFoundException {
|
||||
RepositoryMethodInvoker repoMethodInvoker = repoRequest.getRepositoryMethodInvoker();
|
||||
final RepositoryMethodInvoker repoMethodInvoker = repoRequest.getRepositoryMethodInvoker();
|
||||
if(null == repoMethodInvoker || (!repoMethodInvoker.hasFindOne()
|
||||
&& !(repoMethodInvoker.hasDeleteOne() || repoMethodInvoker.hasDeleteOneById()))) {
|
||||
throw new NoSuchMethodError();
|
||||
}
|
||||
|
||||
Object domainObj = domainClassConverter.convert(id,
|
||||
STRING_TYPE,
|
||||
TypeDescriptor.valueOf(repoRequest.getPersistentEntity()
|
||||
.getType()));
|
||||
final Object domainObj = domainClassConverter.convert(id,
|
||||
STRING_TYPE,
|
||||
TypeDescriptor.valueOf(repoRequest.getPersistentEntity()
|
||||
.getType()));
|
||||
if(null == domainObj) {
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
applicationContext.publishEvent(new BeforeDeleteEvent(domainObj));
|
||||
if(repoMethodInvoker.hasDeleteOneById()) {
|
||||
Class<? extends Serializable> idType = (Class<? extends Serializable>)repoRequest.getPersistentEntity()
|
||||
.getIdProperty()
|
||||
.getType();
|
||||
Object idVal = conversionService.convert(id, idType);
|
||||
repoMethodInvoker.delete((Serializable)idVal);
|
||||
} else if(repoMethodInvoker.hasDeleteOne()) {
|
||||
repoMethodInvoker.delete(domainObj);
|
||||
TransactionCallbackWithoutResult callback = new TransactionCallbackWithoutResult() {
|
||||
@Override protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
if(repoMethodInvoker.hasDeleteOneById()) {
|
||||
Class<? extends Serializable> idType = (Class<? extends Serializable>)repoRequest.getPersistentEntity()
|
||||
.getIdProperty()
|
||||
.getType();
|
||||
final Serializable idVal = conversionService.convert(id, idType);
|
||||
repoMethodInvoker.delete(idVal);
|
||||
} else if(repoMethodInvoker.hasDeleteOne()) {
|
||||
repoMethodInvoker.delete(domainObj);
|
||||
}
|
||||
}
|
||||
};
|
||||
if(null != txTmpl) {
|
||||
txTmpl.execute(callback);
|
||||
} else {
|
||||
callback.doInTransaction(null);
|
||||
}
|
||||
applicationContext.publishEvent(new AfterDeleteEvent(domainObj));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user