问题
I have some objects I cannot delete, and must update a common field named 'deleted' instead of it. I read there that I can write generic querys, using #{#entityName}
.
For that reason I tried to override CrudRepository#delete(…)
method like this:
public interface DeleteableRepository<T, ID extends Serializable> extends CrudRepository<T,ID>{
@Override
@Query("UPDATE #{#entityName} x set x.deleted = 1 where x.id = ?1")
public void delete(ID id);
}
But the I have a unit test that shows me wrong!
@Test
public void testDelete() {
SomeDeleteableObject sdo = new SomeDeletableObject();
sdo = getDeleteableRepository().create(sdo);
Assert.assertNotNull(sdo);
Assert.assertNotNull(sdo.getId());
Assert.assertFalse(sdo.isDeleted());
getDeleteableRepository().delete(sdo);
sdo = getDeleteableRepository().findOne(sdo.getId());
//Fails here
}
Isn't it possible to override CrudRepository
methods like that?
回答1:
For modifying queries you need to add an @Modifying
to the method.
Be sure you are aware of the side effects of the approach you chose:
- Executing a manipulating query is pretty much bypassing all
EntityManager
caches. Thus a subsequentfindOne(…)
might/will still return the old instance of the object you tried to delete in case theEntityManager
had already loaded it. To prevent that, set theclearAutomatically
flag in@Modifying
totrue
but be aware that this will cause all pending changes being wiped out. - For query based data manipulation no lifecycle callbacks will be triggered and no cascades will be triggered on the level of the persistence context. This means, entity listeners listening to an
@PreUpdate
event will not get notified. Also any cascade operations
来源:https://stackoverflow.com/questions/23173273/how-to-override-a-delete-method-on-a-spring-data-crudrepository