当前位置: 首页 > 知识库问答 >
问题:

使用@IdClass保存实体会产生空行

冉锋
2023-03-14

我想将行保存在一个简单的表中,该表包含另外两个实体的ID。经过一些尝试,我得到了以下配置。Spring Boot现在可以正确地创建表,列名称为task\u run\u id和project\u id。

但当我调用repo时。保存(参与者)创建了一行,但两列都包含0,而不是所需的ID。不会引发任何错误。

我做错了什么?此外,如果有一些声明对于实现简单的保存和以后的查询是不必要的,请告诉我。

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

共有1个答案

裴英才
2023-03-14

看起来您只能将MapsId注释与由@EmbeddedId注释映射的om的标识符一起使用。

根据MapsId注释的文档:

指定ManyToOneOneToOne关系属性,该属性提供EmbeddedId主键、EmbeddedId主键中的属性或父实体的简单主键的映射。value元素指定关系属性对应的复合键中的属性。

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

java prettyprint-override">@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;
   }
}

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

 类似资料:
  • 我试图创建一个注册用户的功能。 我遵循了这篇文章中的建议:将空作为id保存,并Hibernate,但解决方案对我不起作用。这是我的用户类 这是我的账户类 我的日志显示了以下输出

  • 我有以下实体: 我第一次使用复合主键,所以我不知道它应该如何工作。问题可能来自定义。第二个参数应该表示ID。但是没有一个主键,而是有两个主键,所以我认为我应该将id类添加到id参数中,但这不起作用。如何使用带有CrudRepository的IdClass键保存具有复合主实体?

  • 我是JPA和Spring的初学者。这也是我的第一个问题。所以,为我的错误道歉。我正在练习以简单的场景作为开始。我有两个实体作为产品和类别,具有双向多对一/一对多关联。 类别类: 产品类别: CategoryRepository和ProductRepository都是从JpaRepository实现的。很少有带有@Query注释的方法签名。 使用@autowmed存储库的服务。没有任何商业逻辑。 类

  • 我们正在上运行spark 2.3.0。以下“”不是空的,大小适中: 以下代码可以很好地将写入: 然而,使用相同的代码写入本地< code>parquet或< code>csv文件最终会得到空结果: 我们可以看到它失败的原因: 因此,没有正在写入镶木地板文件。 我已经对< code>csv和< code>parquet以及两个不同的< code>EMR服务器尝试了大约二十次:在所有情况下都表现出相同

  • 我有两个实体 实体1 实体2 我对Jpa不是很熟悉,所以如果您需要对我的问题进行任何澄清,或者您需要任何更多的信息,请告诉我。

  • 我想保存两个实体的差异。旧实体有一个id女巫不是空的。新的id值为null,所以我将它们作为ValueObject进行比较。问题是ValueChange确实保存了差异,但没有保存旧的id。ich如何做到这一点?