【问题标题】:JPA: Use a multiple One-to-many relationships with composite keysJPA:使用复合键的多个一对多关系
【发布时间】:2017-07-26 15:05:06
【问题描述】:

我有这些实体:

Run实体:

@Entity
@Table(name = "run")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, 
property = "runId")
public class Run implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "run_id")
    private Long runId;

    @Column(name = "status")
    private Integer status;

    @Column(name = "create_date")
    private Date date;

    @Column(name = "config_id")
    private Long configId;

    @Column(name = "stream_id")
    private Long streamId;

    @OneToOne(mappedBy = "run", cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "run_id", unique = true, nullable = true, insertable = true, updatable = true)
    private StreamRun streamRun;
    ...
}

StreamRun实体:

@Entity
@Table(name = "stream_run")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, 
property = "streamId")
public class StreamRun implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "id")
    private Long streamId;

    @Column(name = "run_id", insertable = false, updatable = false)
    private Long runId;

    @Column(name = "stream_name")
    private String streamName;

    @OneToOne
    @JoinColumn(name = "run_id")
    private Run run;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "stream", orphanRemoval = true, targetEntity = JobRun.class)
    private List<JobRun> jobs = new ArrayList<>();

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "streamRun", orphanRemoval = true, targetEntity = StreamEvent.class)
    private List<StreamEvent> events = new ArrayList<>();

    ....
    }

JobRun实体:

    @Entity
    @Table(name = "jobs_run")
    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, 
    property = "id")
    @IdClass(JobRunKey.class)
    public class JobRun implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "id")
    private Long id;

    @Id
    @Column(name = "run_id", insertable = false, updatable = false)
    private Long runId;

    @Column(name = "name")
    private String name;

    @Column(name = "type")
    private String jobType;

    @Column(name = "script")
    private String script;

    @Column(name = "status")
    private Integer status;

    @ManyToOne
    @JoinColumns({ @JoinColumn(name = "run_id", referencedColumnName = "run_id"), @JoinColumn(name = "job_stream_id", referencedColumnName = "id") })
    private StreamRun stream;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "jobRun", orphanRemoval = true, targetEntity = JobDependencyRun.class)
    public List<JobDependencyRun> dependencies = new ArrayList<>();

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "jobRun", orphanRemoval = true, targetEntity = JobEvent.class)
    public List<JobEvent> events = new ArrayList<>();

    ....
}

所有列都定义在 MySQL 数据库中,表job_run 的组合键为(idrun_id)。

问题出在JobRun实体:

  • 如果我将“run_id”字段定义为@ID,则会出现异常(插入时)

    参数索引超出范围(8>参数个数,即7)。

  • 如果我在没有@ID 的情况下定义它,则会出现异常(更新时)

    键“PRIMARY”的重复条目“4-78”

  • 如果我从实体中删除整个字段定义,因为它是外键,那么例外情况是:

    找不到逻辑名称为run_id的列​​

    “虽然该列存在于表中”。

请问,谁能帮帮我?
我在代码中做错了吗?

【问题讨论】:

    标签: java mysql sql hibernate jpa


    【解决方案1】:

    我设法找到了解决方案,通过如下修改JobRun 实体,并从直接setter 和getter 方法更改\访问runId 的值。

    @Entity
    @Table(name = "jobs_run")
    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, 
    property = "id")
    @IdClass(JobRunKey.class)
    public class JobRun implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @Id
        @Column(name = "id")
        private Long id;
    
        @Id
        @Column(name = "run_id")
        private Long runId;
    
        @Column(name = "job_stream_id")
        private Long streamId;
    
        @Column(name = "name")
        private String name;
    
        @Column(name = "type")
        private String jobType;
    
        @Column(name = "script")
        private String script;
    
        @Column(name = "status")
        private Integer status;
    
        @ManyToOne
        @JoinColumns({ @JoinColumn(name = "run_id", referencedColumnName = "run_id", insertable = false, updatable = false),
                @JoinColumn(name = "job_stream_id", referencedColumnName = "id", insertable = false, updatable = false) })
        private StreamRun stream;
    
        @OneToMany(cascade = CascadeType.ALL, mappedBy = "jobRun", orphanRemoval = true, targetEntity = JobDependencyRun.class)
        public List<JobDependencyRun> dependencies = new ArrayList<>();
    
        @OneToMany(cascade = CascadeType.ALL, mappedBy = "jobRun", orphanRemoval = true, targetEntity = JobEvent.class)
        public List<JobEvent> events = new ArrayList<>();
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 2015-12-13
      • 2011-01-23
      • 1970-01-01
      • 2019-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 2021-12-01
      相关资源
      最近更新 更多