【问题标题】:Spring Data @JoinColumn and Entity UpdateSpring Data @JoinColumn 和实体更新
【发布时间】:2019-12-21 15:50:57
【问题描述】:

首先,我没有给这个问题一个合适的标题。随时更新。

问题陈述

我有以下实体:

@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)
}

如果我更新lastScreenId,我希望更新lastScreen 对象。例如,我使用session.setLastScreenId(2)lastScreenId1 设置为2 我希望lastScreen 对象成为ID 为2 的对象

所以这是我尝试过的:

  1. 只需更新lastScreenId。我预计 lastScreen 对象会更新,因为 session 对象仍然是 MANAGED 实体

    失败,因为 lastScreen 对象仍然是前一个对象

  2. 更新lastScreenId并使用SessionRepository保存session对象,并将当前session对象替换为保存在数据库中的新session对象

    session= sessionRepository.save(screen);

    由于lastScreen 对象未从数据库中提取而失败

  3. 使用另一种方法保存session 与不同的事务

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

    这个也失败了。

【问题讨论】:

  • 这不是您更新参考的方式。删除lastScreenId 字段并将@JoinColumn 设置为insertable = true, updatable = true。然后将整个Screen 对象设置为Session,然后将该更改保存到数据库
  • @XtremeBaumer 这更像是一个答案而不是评论。如果您能得到完整的答案,请将其添加为一个:)

标签: java hibernate spring-data-jpa


【解决方案1】:

您需要在同一对象中复制映射“last_screen_id”列的任何原因?

如果不是,我建议您将其更改为仅将其映射到更简单的Screen 实体:

@Entity
public class Session {

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

}

要将 Screen 从 ID 1 更新为 ID 2 ,您必须首先获取新 Screen 并将其设置为 SessionlastScreen. 如果没有新的 Screen 的 ID 则抛出异常:

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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多