简体   繁体   中英

Spring Data @JoinColumn and Entity Update

First of all, I lacked the appropriate title to give to this question. Feel free to update it.

Problem Statement

I have the following entity:

@Entity
public class Session {
    @Column(name = "last_screen_id")
    private Long lastScreenId;

    @JoinColumn(name = "last_screen_id", referencedColumnName = "id", insertable = false, updatable = false)
    @OneToOne
    private Screen lastScreen;

    // Getters and setters for lastScreenId
    // Getter for lastScreen (I don't have a setter for lastScreen object since lastScreen object is marked as insertable=false and updatable=false)
}

If I update the lastScreenId I want the lastScreen object to be updated. For example I set the lastScreenId from 1 to 2 using session.setLastScreenId(2) I want the lastScreen object to be the object with id 2

So here is what I have tried:

  1. Just update the lastScreenId . I expected the lastScreen object to be updated since the session object is still a MANAGED entity

    Fails since the lastScreen object remains to be the previous object

  2. Update the lastScreenId and save the session object using a SessionRepository and replace the current session object to the new session object saved in the database

    session= sessionRepository.save(screen);

    Fails since the lastScreen object is not pulled from the database

  3. Use another method to save the session with a different transaction

      @Transactional(Transactional.TxType.REQUIRES_NEW) public Session saveSessionInANewTransaction(Session session) { return sessionRepository.save(session); } 

    This one fails too.

Any reason that you need to duplicate mapping the "last_screen_id" column in the same object ?

If not , I suggest you to change it to only map it to a Screen entity which is much more simple:

@Entity
public class Session {

    @JoinColumn(name = "last_screen_id", referencedColumnName = "id")
    @OneToOne
    private Screen lastScreen;

}

To update the Screen from ID 1 to ID 2 , you have to first get new Screen and set it to the Session 's lastScreen. Throw exception if there is no ID for the new Screen :

public void updateSessionLastScreen(Long sessionId, Long newScreenId){
    Session session  = sessionRepository.findbyId(sessionId).orElseThrow(()-> new RuntimeException("Session does not exist"));  
    Screen newScreen = screenRepository.findById(newScreenId).orElseThrow(()-> new RuntimeException("Screen does not exist")); 
    session.setLastScreen(newScreen);
}

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