【问题标题】:Attempted to assign id from null one-to-one property in spring boot尝试在 Spring Boot 中从 null 一对一属性分配 id
【发布时间】:2018-10-21 16:21:26
【问题描述】:

我在 spring boot 中有这个错误:

尝试从空的一对一属性 [com.endoorment.models.entity.ActionLang.action] 分配 id

我的代码:

    @Embeddable
public class ActionLangId implements Serializable {

 private static final long serialVersionUID = 1 L;

 @NotNull
 @Column(name = "actions_id")
 private Integer actionId;

 @NotNull
 @Column(name = "langs_id")
 private Integer langId;

 public ActionLangId() {}

 public ActionLangId(Integer actionId, Integer langId) {
  super();
  this.actionId = actionId;
  this.langId = langId;
 }

 public Integer getActionId() {
  return actionId;
 }

 public void setActionId(Integer actionId) {
  this.actionId = actionId;
 }

 public Integer getLangId() {
  return langId;
 }

 public void setLangId(Integer langId) {
  this.langId = langId;
 }

 @Override
 public boolean equals(Object o) {
  if (this == o) return true;
  if (o == null || getClass() != o.getClass())
   return false;

  ActionLangId that = (ActionLangId) o;
  return Objects.equals(actionId, that.actionId) &&
   Objects.equals(langId, that.langId);
 }

 @Override
 public int hashCode() {
  return Objects.hash(actionId, langId);
 }
}

@Entity
@Table(name = "actions_langs")
public class ActionLang {

 @EmbeddedId
 private ActionLangId id;

 @ManyToOne(fetch = FetchType.LAZY)
 @MapsId("actionId")
 @JoinColumn(name = "actions_id")
 private Action action;

 @ManyToOne(fetch = FetchType.LAZY)
 @MapsId("langId")
 @JoinColumn(name = "langs_id")
 private Lang lang;

 @NotNull(message = "null")
 @Size(max = 45, message = "short")
 private String name;

 public ActionLang() {}

 public ActionLang(ActionLangId actionlangid, String name) {
  this.id = actionlangid;
  this.name = name;
 }


 public ActionLangId getId() {
  return id;
 }

 public void setId(ActionLangId id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 @Override
 public String toString() {
  return "ActionLang [id=" + id + ", name=" + name + "]";
 }
}

服务:

@Transactional
public ActionLang saveAction(Integer idlang, String name) {

 Integer id = actionRepository.findActionId();

 Action action = new Action(id);
 actionRepository.save(action);

 ActionLang actionlang = new ActionLang(new ActionLangId(id, idlang), name);
 actionlangRepository.save(actionlang);
 return actionlang;
}

Structure actionlang: {
  "id": {
   "actionId": 2,
   "langId": 1
  },
  "name": "hkjhlhklhkllñkñl"

谢谢

【问题讨论】:

  • 我们缺少可能对您的解决方案很重要的代码。首先,这个actionRepository.findActionId() 是什么,其次,你能分享一下你的动作实体吗?
  • actionRepository.findActionId() 是计算的ID,第一个可用的Id。为了保存 actionlang,我不使用 action。我之前保存过操作。

标签: java spring spring-data-jpa


【解决方案1】:

我的解决方案,

实体动作:

@Entity 
@Table(name = "actions")
public class Action {

@Id
private Integer id;

    @OneToMany(mappedBy = "action")
    private List<ActionLang> actionlang = new ArrayList<>();

 public Action() { }

public Action(Integer id) {this.id = id;}

public Integer getId() {return id;}

public void setId(Integer id) {this.id = id;}

public List<ActionLang> getActionLang() {return actionlang;}

public void addActionLang(ActionLang actionlang) {
    this.actionlang.add(actionlang);
}

public void removeActionLang(ActionLang actionlang) {
    this.actionlang.remove(actionlang);
}

@Override
public String toString() {return "id: " + id ;}
}

实体动作语言,

@Entity 
@Table(name = "actions_langs")
public class ActionLang {

@EmbeddedId
private ActionLangId id;

@ManyToOne(fetch = FetchType.LAZY)
@MapsId("actionId")
@JoinColumn(name = "actions_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonIgnore
private Action action;

@ManyToOne(fetch = FetchType.LAZY)
@MapsId("langId")
@JoinColumn(name = "langs_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonIgnore
private Lang lang;

@NotNull(message="null")
@Size(max = 45, message="short")
private String name;

public ActionLang() {}

public ActionLang(ActionLangId actionlangid, String name) {
    this.id = actionlangid;
    this.name = name;
}

public ActionLangId getId() {return id;}

public String getName() {return name;}

public void setName(String name) {this.name = name;}

public void setId(ActionLangId id) {this.id = id;}

    public Action getAction() {return action;}

public void setAction(Action action) {this.action = action;}

public Lang getLang() {return lang;}

public void setLang(Lang lang) {    this.lang = lang;   }

@Override
public String toString() {return "ActionLang [id=" + id + ", name=" + name + "]";   }
}

服务

@Component
public class ActionDAOService {

@Autowired
    private IActionDao actionRepository;

@Autowired
    private IActionLangDao actionlangRepository;

@Transactional
public Action saveAction(Integer idlang, String name){

    Lang lang = new Lang();
    lang.setId(idlang);

    Integer id = actionRepository.findActionId();
    if(id == null) {
        id=(Integer) 1;
    }

    Action action = new Action(id);
    actionRepository.save(action);

    ActionLang actionlang = new ActionLang(new ActionLangId(id, idlang),name);
    action.addActionLang(actionlang);
    actionlang.setAction(action);
    actionlang.setLang(lang);

    actionlangRepository.save(actionlang);

    return action;
}
}

【讨论】:

    【解决方案2】:

    我修改了服务,还是出现同样的错误

    @Transactional
    public Action saveAction(Integer idlang, String name){
        Integer id = actionRepository.findActionId();
        if(id == null) {id=(Integer) 1;}
        Action action = new Action(id);
        ActionLang actionlang = new ActionLang(new ActionLangId(id, idlang),name);
        action.getActionlang().add(actionlang);
        actionRepository.save(action);
        return action;
    } 
    

    动作的结构是这样的:

    {
        "id": 2,
        "actionlang": [
            {
                "id": {
                    "actionId": 2,
                    "langId": 1
                },
                "name": "hkjhlhklhkllñkñl"
            }
        ]
    }
    

    【讨论】:

      【解决方案3】:

      实体动作

      @Entity 
      @Table(name = "actions")
      public class Action {
      
          @Id
          private Integer id;
      
          @OneToMany(mappedBy = "action", cascade = CascadeType.ALL, orphanRemoval = true)
          private List<ActionLang> actionlang = new ArrayList<>();
      
          public Action() {
          }
      
          public Action(Integer id) {
              super();
              this.id = id;
          }
      
          public Integer getId() {
              return id;
          }
      
          public void setId(Integer id) {
              this.id = id;
          }
      
          public List<ActionLang> getActionlang() {
              return actionlang;
          }
      
          @Override
          public String toString() {
              return "Action [id=" + id + ", actionlang=" + actionlang + ", getId()=" + getId() + ", getActionlang()="
                      + getActionlang() + ", getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()="
                      + super.toString() + "]";
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2019-11-28
        • 2012-06-21
        • 2021-10-14
        • 1970-01-01
        • 2022-07-08
        • 1970-01-01
        • 2021-06-08
        • 2021-01-16
        • 2021-12-25
        相关资源
        最近更新 更多