简体   繁体   中英

Entity gets detached when should be managed

Consider Controller-Service-Repository arch.

Successful method in TokenService declaring that I am correct to the point.

@Transactional
public Token getByString(String tokenString) {


    Token t = tr.loadTokenByString(tokenString);

    t.setTokenType("SERVICE MODIF"); // note this test line works and changes are propagated to db
    em.flush();


    return t;
}

Now we are inside controller handler mapping calling previous service method and extracting the token:

logger.info(urlToken);

        Object obj;

        Token token;

        obj = tokenService.getByString(urlToken);
        User u;
        if (obj != null) {



            token = (Token) obj;

            // tokenService.save(token); - am angry lost detached entity throwing exception that i am detached

            token.setTokenType("helllo"); // this does not propagate to db since entity is detached


            logger.info(token.toString());

            u = token.getUser();
            userService.activateUser(u);

        }

As you can see from the comments the next setTokenType inside controller call does not do anything thus I called save to check the state which without further guessing notified me that entity became detached.

Does it imply that I have to do all the changes inside service classes? What's wrong with controller context, if I just need to call one mutator I don't want to be forced to create a whole chain of repository-service to make it from controller Oo

I recall somewhere deep in my brain that there is a requirement for some magical filter to account for controller context, but that was long time ago and I cannot recall what kind of filter is required. Maybe I am completely wrong.

I doubt I would able to merge inside controller since asfaik even .flush throws exception whenever I forget to declare service transactional. And I doubt it is either possible or even correct to declare controller handler method transactional and autowire persistence context directly just to call merge.

Ideal scenario of course would be to maintain persistent state of the entity even when it gets retrieved by Controller chain call.

When you declare that method transactional it will be transactional. That and only that.

After the transaction is complete you cannot make any changes to that in a sense that whatever the reference object you have associated with that is no longer managed by the session. (Because the transaction is over).

If you want to change the object in a managed state do that in the transactional method it self (within the same transaction).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM