使用@IdClass 保存实体会产生空行 [英] Saving entity with @IdClass produces empty row

查看:32
本文介绍了使用@IdClass 保存实体会产生空行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将行保存在一个包含其他两个实体的 ID 的简单表中.经过一些尝试,我得到了以下配置.Spring Boot 现在可以正确创建表,列名为 task_run_idproject_id.

但是当我调用 repo.save(participant) 时,会创建一行,但两列都包含 0,而不是所需的 id.不会抛出任何错误.

我做错了什么?另外如果有一些不需要实现简单保存和后续查询的声明,请告诉我.

@Entity@IdClass(TaskRunParticipant.Id.class)公共类 TaskRunParticipant 实现了 Serializable {@javax.persistence.Id@Column(name = "run_id")私人长期运行Id;@javax.persistence.Id@Column(name = "project_id")私人长项目Id;@OneToOne@JoinColumn(name="project_id")@MapsId("project_id")私人项目项目;@OneToOne@JoinColumn(name="run_id")@MapsId("run_id")私人任务运行任务运行;受保护的 TaskRunParticipant(){}公共TaskRunParticipant(TaskRun运行,项目项目){this.taskRun = 运行;this.project = 项目;}公共项目 getProject() { 返回项目;}public void setProject(Project project) { this.project = project;}public TaskRun getTaskRun() { return taskRun;}public void setTaskRun(TaskRun taskRun) { this.taskRun = taskRun;}protected long getRunId(){ return runId;}protected long getProjectId(){ return projectId;}protected void setRunId(long runId){ this.runId = runId;}protected void setProjectId(long projectId){ this.projectId = projectId;}公共最终静态类 ID 实现可序列化 {私人长期身份;私人长项目Id;public long getRunId() { return runId;}public void setRunId(long runId) { this.runId = runId;}public long getProjectId() { return projectId;}public void setProjectId(long projectId) { this.projectId = projectId;}@覆盖公共布尔等于(对象 o){if (this == o) 返回真;if (o == null || getClass() != o.getClass()) 返回假;id id = (Id) o;返回 runId == id.runId &&projectId == id.projectId;}@覆盖公共 int hashCode() {返回 Objects.hash(runId, projectId);}}}

解决方案

看起来您只能将 MapsId 注释与 @EmbeddedId 映射的复合标识符一起使用注释.>

根据文档MapsId 注释:

<块引用>

指定一个 ManyToOneOneToOne 关系属性,为 EmbeddedId 主键提供映射,EmbeddedId 主键,或父实体的简单主键.value 元素指定关系属性对应的组合键中的属性.

因此,我建议您按以下方式重写映射:

@Embeddable公共类 TaskRunParticipantId 实现了可序列化{私人长期运行ID;私人长项目ID;公共 TaskRunParticipantId(){}public TaskRunParticipantId(Long runId, Long projectId){this.runId = runId;this.projectId = projectId;}公共长 getRunId(){返回运行ID;}public void setRunId(Long runId){this.runId = runId;}公共长 getProjectId(){返回项目ID;}public void setProjectId(Long projectId){this.projectId = projectId;}@覆盖公共布尔等于(对象 o){if (this == o) 返回真;if (o == null || getClass() != o.getClass()) 返回假;TaskRunParticipantId id = (TaskRunParticipantId) o;返回 runId == id.runId &&projectId == id.projectId;}@覆盖公共 int hashCode(){返回 Objects.hash(baseModelId, otherEntityId);}}@实体公共类 TaskRunParticipant{私有 TaskRunParticipantId id;私人项目项目;私人任务运行任务运行;公共 TaskRunParticipant(){id = new TaskRunParticipantId();}公共TaskRunParticipant(项目项目,TaskRun taskRun){这();this.project = 项目;this.taskRun = taskRun;}@EmbeddedId公共 TaskRunParticipantId getId(){返回标识;}public void setId(TaskRunParticipantId id){this.id = id;}@OneToOne@JoinColumn(name="project_id")@MapsId("projectId")公共项目 getProject(){回归项目;}public void setProject(项目项目){this.project = 项目;}@OneToOne@JoinColumn(name="run_id")@MapsId("runId")公共 TaskRun getTaskRun(){返回任务运行;}public void setTaskRun(TaskRun taskRun){this.taskRun = taskRun;}}

请注意,MapsId 中的值是 TaskRunParticipantId 类中相应字段的名称,而不是列名称.

I'd like to save rows in a simple table that contains the ids of two other entities. After some tries, I arrived at the following configuration. Spring Boot now correctly creates the table, with column names task_run_id and project_id.

But when I call repo.save(participant) a row is created but both columns contain 0, instead of the required ids. No error is thrown.

What am I doing wrong? Also if there there are some declarations that are unnecessary to achieve a simple save and later query, please tell me.

@Entity
@IdClass(TaskRunParticipant.Id.class)
public class TaskRunParticipant implements Serializable {

   @javax.persistence.Id
   @Column(name = "run_id")
   private long runId;

   @javax.persistence.Id
   @Column(name = "project_id")
   private long projectId;

   @OneToOne
   @JoinColumn(name="project_id")
   @MapsId("project_id")
   private Project project;

   @OneToOne
   @JoinColumn(name="run_id")
   @MapsId("run_id")
   private TaskRun taskRun;

   protected TaskRunParticipant(){}
    
   public TaskRunParticipant(TaskRun run, Project project){
      this.taskRun = run;
      this.project = project;
   }
    
   public Project getProject() { return project; }
   public void setProject(Project project) { this.project = project; }
   public TaskRun getTaskRun() { return taskRun; }
   public void setTaskRun(TaskRun taskRun) { this.taskRun = taskRun; }
   protected long getRunId(){ return runId; }
   protected long getProjectId(){ return projectId; }
   protected void setRunId(long runId){ this.runId = runId; }
   protected void setProjectId(long projectId){ this.projectId = projectId; }

   public final static class Id implements Serializable {
       private long runId;
       private long projectId;

       public long getRunId() { return runId; }
       public void setRunId(long runId) { this.runId = runId; }
       public long getProjectId() { return projectId; }
       public void setProjectId(long projectId) { this.projectId = projectId; }

       @Override
       public boolean equals(Object o) {
           if (this == o) return true;
           if (o == null || getClass() != o.getClass()) return false;
           Id id = (Id) o;
           return runId == id.runId &&
           projectId == id.projectId;
       }
    
       @Override
       public int hashCode() {
           return Objects.hash(runId, projectId);
       }
   }
}

解决方案

It looks like that you can use the MapsId annotation only with сomposite identifiers mapped by the @EmbeddedId annotation.

According to the documentation for the MapsId annotation:

Designates a ManyToOne or OneToOne relationship attribute that provides the mapping for an EmbeddedId primary key, an attribute within an EmbeddedId primary key, or a simple primary key of the parent entity. The value element specifies the attribute within a composite key to which the relationship attribute corresponds.

So, I would suggest you to rewrite your mapping in the following way:

@Embeddable
public class TaskRunParticipantId implements Serializable
{
   private Long runId;
   private Long projectId;
   
   public TaskRunParticipantId()
   {
   }
   
   public TaskRunParticipantId(Long runId, Long projectId)
   {
      this.runId = runId;
      this.projectId = projectId;
   }

   public Long getRunId()
   {
      return runId;
   }
   public void setRunId(Long runId)
   {
      this.runId = runId;
   }

   public Long getProjectId()
   {
      return projectId;
   }
   public void setProjectId(Long projectId)
   {
      this.projectId = projectId;
   }

   @Override
   public boolean equals(Object o)
   {
       if (this == o) return true;
       if (o == null || getClass() != o.getClass()) return false;
       TaskRunParticipantId id = (TaskRunParticipantId) o;
       return runId == id.runId &&
             projectId == id.projectId;
   }

   @Override
   public int hashCode()
   {
       return Objects.hash(baseModelId, otherEntityId);
   }
}

@Entity
public class TaskRunParticipant
{
   private TaskRunParticipantId id;
   private Project project;
   private TaskRun taskRun;
   
   public TaskRunParticipant()
   {
      id = new TaskRunParticipantId();
   }
   
   public TaskRunParticipant(Project project, TaskRun taskRun)
   {
      this();
      this.project = project;
      this.taskRun = taskRun;
   }
   
   @EmbeddedId
   public TaskRunParticipantId getId()
   {
      return id;
   }
   public void setId(TaskRunParticipantId id)
   {
      this.id = id;
   }

   @OneToOne
   @JoinColumn(name="project_id")
   @MapsId("projectId")
   public Project getProject()
   {
      return project;
   }
   public void setProject(Project project)
   {
      this.project = project;
   }

   @OneToOne
   @JoinColumn(name="run_id")
   @MapsId("runId")
   public TaskRun getTaskRun()
   {
      return taskRun;
   }
   public void setTaskRun(TaskRun taskRun)
   {
      this.taskRun = taskRun;
   }
}

Please note that the value in the MapsId is the name of appropriate field in the TaskRunParticipantId class, not the column name.

这篇关于使用@IdClass 保存实体会产生空行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆