如何使用复合主键建立OneToMany单向关系?

时间:2018-08-03 15:05:51

标签: java jpa

我有两个实体:

表A

public class TableA implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(nullable = false)
    private long id;
    @Basic(optional = false)
    @Size(min = 1, max = 255)
    @Column(nullable = false, length = 255)
    private String someParams;
    @OneToMany(mappedBy = "tableA", cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, orphanRemoval = true)
    private List<TableB> tableB = new ArrayList<>();

public TableA() {}

public long getId() {...}
public void setId(long id) {...}
public String getSomeParams() {...}
public void setSomeParams(String someParams) {...}
public List<TableB> getTableB() {...}
public void setTableB(List<TableB> tableB)
...
}

TableB ,带有复合主键,其中之一也是TableA的外键:

@Embeddable
public class TableBPK implements Serializable {
    private static final long serialVersionUID = 1L;
    @Basic(optional = false)
    @NotNull
    @Column(name = "tableA", nullable = false, insertable = false, updatable = false)
    private long tableA;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 62)
    @Column(name = "param", nullable = false, length = 62, insertable = false, updatable = false)
    private String param;

public TableBPK () {}
public TableBPK (long tableA, String param) {...}

public String getParam() {...}
public void setParam(String param) {...}    
public long getTableA() {...}
public void setTableA(long tableA) {...}
...
}

@Entity
@Table(name = "table_b")
public class TableB implements Serializable {
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected TableBPK tableBPK;
    @Basic(optional = false)
    @Size(min = 1, max = 62)
    @Column(name = "param", nullable = false, length = 62, insertable = true, updatable = true)
    private String param;
    @Size(min = 1, max = 510)
    @Column(length = 510)
    private String value;
    @JoinColumn(name = "tableA", referencedColumnName = "id", nullable = false, insertable = true, updatable = true)
    @ManyToOne(optional = false, cascade = CascadeType.PERSIST)
    private TableA tableA;

public TableB() {}

public TableB(String param, String value, TableA tableA) {
    this.tableBPK = new tableBPK(tableA.getId(), param);
    this.param = param;
    this.value = value;
    this.tableA = tableA;
}

public String getParam() {...}
public void setParam(String param) {...}
public String getValue() {...}
public void setValue(String value) {...}
public TableA getTableA() {...}
public void setTableA(TableA tableA) {...}
public TableBPK getTableBPK() {...}
public void setTableBPK(TableBPK tableBPK) {...}
...
}

双向关系我意识到没有问题,但是我需要建立一个单向关系(从TablaB TableA中删除)。

我执行以下操作:

@Entity
@Table(name = "table_b")
public class TableB implements Serializable {
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected TableBPK tableBPK;
    @Basic(optional = false)
    @Size(min = 1, max = 62)
    @Column(name = "param", nullable = false, length = 62, insertable = true, updatable = true)
    private String param;
    @Size(min = 1, max = 510)
    @Column(length = 510)
    private String value;

public TableB() {}

public TableB(String param, String value, TableA tableA) {
    this.tableBPK = new tableBPK(tableA.getId(), param);
    this.param = param;
    this.value = value;
}
...
}

表A 中更改

@OneToMany(mappedBy = "tableA", cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, orphanRemoval = true)
private List<TableB> tableB = new ArrayList<>();

@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, orphanRemoval = true)
@JoinColumns({
    @JoinColumn(name = "tableA", referencedColumnName = "tableA"),
    @JoinColumn(name = "param", referencedColumnName = "param")
})
private List<TableB> tableB = new ArrayList<>();

我得到例外:

Descriptor Exceptions: 
---------------------------------------------------------
Exception [EclipseLink-46] (Eclipse Persistence Services - 2.6.1.v20150605-31e8258): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: There should be one non-read-only mapping defined for the primary key field [table_b.tableA].
Descriptor: RelationalDescriptor(ru.test.entities.TableB --> [DatabaseTable(table_b)])
Runtime Exceptions: 
---------------------------------------------------------

请告诉我我在做什么错?

0 个答案:

没有答案