2017-07-26 37 views
1

关系,我有这些实体:JPA:1对多用复合键

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

    .... 
    } 

and JobRun entity: 

    @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那么一个异常出现时(更新)

    重复条目 '4-78' 关键 'PRIMARY'

  • 如果我删除来自实体的整个字段的定义,因为它是外键,那么例外将是:

    无法找到具有逻辑名称的列run_id

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

请问任何人都可以帮我吗?
我在代码中做了什么错误吗?

回答

1

我已经设法找到一个解决方案,通过修改JobRun实体如下,并从直接设置和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<>(); 
    ... 
}