2

I need to detach an entity from persistence context, within a spring-boot application.

I have the following base repository:

interface EntityRepository extends CrudRepository<Entity, Long> 

Obviously this is not offering any detach(..)-operation. I found an answer, which is actually not working for me: SO Post.

I tried the same, but it seems that my entity is not detached(as if im changing any field, it gets still persisted)

Custom Repo:

interface MyCustomEntityRepository {
  void detach(Entity ent)
}

Interface Impl:

class MyCustomEntityRepositoryImpl implements MyCustomEntityRepository{
     @PersistenceContext
     private EntityManager em;

     public void detach(Entity ent) {
         em.detach(ent);
     }
}

But I cant extend EntityRepository with MyCustomEntityReposity, as this results in:

No property detach found for type Entity! I managed to get it compiled without errors, by not extending EntityRepository. Also changin CrudRepository to JpaRepository But still my entity is not getting detached, but in linked post, the QA says, that it is working for him/her. The actual reason for detaching the object, is to be able to perform some validations within an @EntityListener, by checking the currently stored entity in db, with the currently changed entity instance, which should be detached.

Does anyone see some errors or give me a clue, what Im doing wrong ?

Using: Spring-boot(1.4.0-release), Spring 4, JPA

Community
  • 1
  • 1
lunatikz
  • 716
  • 1
  • 11
  • 27
  • Is this a one-off requirement or do you want this facility for all entities in your application? – manish Oct 14 '16 at 05:13
  • I need it for one entity only, but would be interested in the general approach, too – lunatikz Oct 14 '16 at 08:19
  • If it is for a single entity only, just autowire `EntityManager` as `@PersistenceContext EntityManager entityManager;` where you autowire the repository and then you can detach entity instances as `entityManager.detach(entity)`. This does not require any custom coding so is easy. If you require this for all entities, see [the official documentation](http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-behaviour-for-all-repositories) on custom behaviour for JPA repositories. You can extend `CrudRepository` to include a `detach` method on the repository. – manish Oct 14 '16 at 08:26
  • I actually do what you mention in the last sentence, but spring claims: `Error creating bean with name 'entityRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property detach found for type Entity` – lunatikz Oct 14 '16 at 08:29
  • You are not introducing custom behaviour for all repositories but only one repository (from your code). Adding behaviour to all repositories requires an interface extending from `CrudRepository`, `PagingAndSortingRepository` or `JpaRepository`, a repository class extending `SimpleJpaRepository` and implementing the custom interface and a factory bean that can create instances of the custom repository class. See the exact section in the documentation I have linked to. – manish Oct 14 '16 at 08:33
  • Hm, i tried a kind of simple examples, which are quite similar to the mentioned documentation. But apparently, it had not worked. Due to less time, I had to solve it without detaching.. I will create in a few days a simple example and try it out again, I will then reply here and let u know, if it had worked – lunatikz Oct 18 '16 at 11:22
  • See my [sample application](https://github.com/manish-in-java/spring-jpa-hibernate) for an example of custom repository implementation. I have implemented the `detach` method in addition to other methods exposed by `EntityManager`. – manish Oct 18 '16 at 11:54

1 Answers1

1

Does anyone see some errors or give me a clue, what Im doing wrong?

Although it is hard to tell, what might be part of your actual problem and what is just sloppy question editing.

  1. Your interface does not compile

    interface MyCustomEntityRepository {
       detach(Entity ent)
    }
    

    should probably be

    interface MyCustomEntityRepository {
       void detach(Entity ent)
    }
    
  2. Your implementation of your custom interface should implement the interface:

    class MyCustomEntityRepositoryImpl {
    

    should probably be

    class MyCustomEntityRepositoryImpl implements MyCustomEntityRepository {
    

If problems persist, please show the actual code you are using with the actual exception, including the stacktrace.

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
  • Sorry for the late reply. Yes, the errors in code happened due the sloppy question editing. I could solve it, by not using detaching at all, instead I parse the modifications on another entity instance and am able to do the validations on two seperated entity instances. I will try it out again in a few days to achieve the same with entity listener and detaching, as i am interested in it for myself. I will then reply here. Sorry for the delay – lunatikz Oct 18 '16 at 11:21