简体   繁体   中英

Spring Data JPA updates entity when I don't want it to

I have a situation where I want to retrieve data, but before it is returned I want to change it without saving/persisting.

Here is my rest controller:

@RestController
@RequestMapping("api/drawing-releases")
@CrossOrigin("*")
public class DrawingReleaseRestController {
    @Autowired
    private DrawingReleaseService service;

    @RequestMapping(method = RequestMethod.GET, value = "/{id}")
    @JsonView(View.DrawingReleaseView.class)
    public ResponseEntity<DrawingRelease> getWithId(@PathVariable int id) throws EntityNotFoundException {
      return new ResponseEntity<>(service.getByID(id),HttpStatus.OK);
    }
}

Here is the service implementation:

@Service
public class DrawingReleaseServiceImpl extends DrawingFunctions implements DrawingReleaseService {
    /**
     * Logging Manager
     */
    private static final Logger LOGGER=LogManager.getLogger();

    @Autowired
    private DrawingReleaseRepository repository;

    @Override
    public DrawingRelease getByID(int id) throws EntityNotFoundException {
        Optional<DrawingRelease> opt = repository.findById(id);
        ...
        // manipulate the data here
        ...
        return opt.get();
    }
}

Intitially I had the @Transactional annotation on the service. By removing that and not having it on the getByID method, I was first thinking that the session would open and close with the repository as indicated by the answer here .

That did not work, and I saw in the comments that "the session lasts for the entire duration of HTTP request processing." So, in the service I added

@Autowired
private EntityManager em;

and then in the getByID method I added

em.close();

before I made any changes. However, any changes I make are still being persisted.

Is there any way that I can make unsaved changes in my service layer? I suppose I could create some POJOs that mirror the entities (but aren't entities) and then copy the data and return those objects, but it doesn't seem like I should have to do something like that.

是的,您可以detach实体与持久性上下文detachhttps : //docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html#detach-java.lang.Object-

You say you want to get an Entity and then change the data and then return it without the entity being persisted but IMHO you shouldn't be using the entity for this. Why are you changing the data and what is the user going to do with it since it no longer represents what's in the database. What other changes are going to be made or what other assumptions (this is a database object) are going to be invalid?

If you are using a database object to derive a different object you should have a different class for this purpose. This is common and is called a Data Transfer Object (DTO) and they can be created from spring-data-jpa directly using projection. Your Dto object would take an entity as a constructor and fill out whatever properties it wants to from the entity. The Dto is not a persistent object so there are no issues around it being saved.

Much clearer and more understandable design and consistent with SOLID Principles and code structure .

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