java - @OneToMany 关联加入错误的字段

标签 java hibernate

我有 2 个表,devices 其中包含设备列表和 dev_tags,其中包含这些设备的 Assets 标签列表。这些表在 dev_serial_num 上连接,它不是两个表的主键。这些设备的 ip_address 字段是唯一的,并且具有由 dev_id 标识的主键。这些设备在两周后“老化”。因此,同一个硬件可以在设备中多次出现。

我提到这一点是为了解释为什么 dev_tags 和设备之间存在 OneToMany 关系,而这似乎应该是 OneToOne 关系。

所以我有我的 2 个实体

@Entity
@Table(name = "dev_tags")
public class DevTags implements Serializable {

private Integer tagId;
private String devTagId;
private String devSerialNum;
private List<Devices> devices;

@Id
@GeneratedValue
@Column(name = "tag_id")
public Integer getTagId() {
    return tagId;
}

public void setTagId(Integer tagId) {
    this.tagId = tagId;
}

@Column(name="dev_tag_id")
public String getDevTagId() {
    return devTagId;
}

public void setDevTagId(String devTagId) {
    this.devTagId = devTagId;
}

@Column(name="dev_serial_num")
public String getDevSerialNum() {
    return devSerialNum;
}

public void setDevSerialNum(String devSerialNum) {
    this.devSerialNum = devSerialNum;
}


@OneToMany(mappedBy="devSerialNum")
public List<Devices> getDevices() {
    return devices;
}

public void setDevices(List<Devices> devices) {
    this.devices = devices;
}


}

还有这个

public class Devices implements java.io.Serializable {

private Integer devId;
private Integer officeId;
private String devSerialNum;
private String devPlatform;
private String devName;
private OfficeView officeView;
private DevTags devTag;

public Devices() {
}

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "dev_id", unique = true, nullable = false)
public Integer getDevId() {
    return this.devId;
}

public void setDevId(Integer devId) {
    this.devId = devId;
}

@Column(name = "office_id", nullable = false, insertable=false, updatable=false)
public Integer getOfficeId() {
    return this.officeId;
}

public void setOfficeId(Integer officeId) {
    this.officeId = officeId;
}

@Column(name = "dev_serial_num", nullable = false, length = 64, insertable=false, updatable=false)
@NotNull
@Length(max = 64)
public String getDevSerialNum() {
    return this.devSerialNum;
}

public void setDevSerialNum(String devSerialNum) {
    this.devSerialNum = devSerialNum;
}

@Column(name = "dev_platform", nullable = false, length = 64)
@NotNull
@Length(max = 64)
public String getDevPlatform() {
    return this.devPlatform;
}

public void setDevPlatform(String devPlatform) {
    this.devPlatform = devPlatform;
}

@Column(name = "dev_name")
public String getDevName() {
    return devName;
}

public void setDevName(String devName) {
    this.devName = devName;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "office_id")
public OfficeView getOfficeView() {
    return officeView;
}

public void setOfficeView(OfficeView officeView) {
    this.officeView = officeView;
}

@ManyToOne()
@JoinColumn(name="dev_serial_num")
public DevTags getDevTag() {
    return devTag;
}

public void setDevTag(DevTags devTag) {
    this.devTag = devTag;
}

}

我用@JoinColumn(name=) 和@OneToMany 的mappedBy 属性搞乱了很多,但我就是无法得到正确的结果。我终于得到了要编译的该死的东西,但查询仍在尝试将 devices.dev_serial_num 连接到 dev_tags.tag_id,即该实体的 @Id。以下是控制台的文字记录:

13:12:16,970 INFO  [STDOUT] Hibernate: 
select
    devices0_.office_id as office5_2_,
    devices0_.dev_id as dev1_2_,
    devices0_.dev_id as dev1_156_1_,
    devices0_.dev_name as dev2_156_1_,
    devices0_.dev_platform as dev3_156_1_,
    devices0_.dev_serial_num as dev4_156_1_,
    devices0_.office_id as office5_156_1_,
    devtags1_.tag_id as tag1_157_0_,
    devtags1_.comment as comment157_0_,
    devtags1_.dev_serial_num as dev3_157_0_,
    devtags1_.dev_tag_id as dev4_157_0_ 
from
    ond.devices devices0_ 
left outer join
    ond.dev_tags devtags1_ 
        on devices0_.dev_serial_num=devtags1_.tag_id 
where
    devices0_.office_id=?
13:12:16,970 INFO  [IntegerType] could not read column value from result set: dev4_156_1_; Invalid value for getInt() - 'FDO1129Y2U4'
13:12:16,970 WARN  [JDBCExceptionReporter] SQL Error: 0, SQLState: S1009
13:12:16,970 ERROR [JDBCExceptionReporter] Invalid value for getInt() - 'FDO1129Y2U4'

getInt() 'FD01129Y2U4' 的值是一个序列号,绝对不是一个 Int!我在这里错过/误解了什么?我可以在我想要的任何字段上连接 2 个表吗?还是至少有一个表必须是主键?

最佳答案

简短的回答是“不,您不能在任何字段上连接 2 个表”;关联将始终引用一侧的主键。

@OneToMany 的“mappedBy”属性用于 bi-directional assocations并将集合元素上映射回所有者实体的属性名称指定为@ManyToOne。就您而言,

@OneToMany(mappedBy="devSerialNum")

声明无效;应改为

@OneToMany(mappedBy="devTag")

相反,如果您想保持双向关系。 @JoinColumn 可以与 @ManyToOne 一起使用来指定指向另一个表的(外键)列的名称。就您而言,

@ManyToOne()
@JoinColumn(name="dev_serial_num")
public DevTags getDevTag() {

声明说您的 devices 表中有一个名为 dev_serial_num 的列,它将是指向 dev_tags.tag_id 的外键,这也是错误的。

我不太清楚你所说的“设备老化”是什么意思,但在我看来,你试图将两个独立的概念合并到一个表中,这就是所有这些问题的根源。考虑将“设备”表(和实体)分成两部分:

  1. “核心”设备(由于缺乏更好的名称)应包含真正唯一的属性,例如序列号。您的 DevTags 实体将作为一对多链接到此实体。
  2. 设备“版本”将包含适用于各个“版本”的属性。每个“核心”设备都会有多个“版本”; “版本”是每两周更新一次的版本。

关于java - @OneToMany 关联加入错误的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1574026/

相关文章:

java - Hibernate 对 findAll() 执行无限查询

java - 正则表达式模式仅匹配 Java 中逗号之间的两个字符

java - 我们如何有效地防止在一个 session 中同时使用 Web 应用程序?

java - 如何通过自定义Struts类型转换器转换列表项的字段?

java - c3p0 getConnection 在连接数增加时挂起

java - 如何从 *.hbm.xml 类生成 Hibernate 映射类

java - 如何使用jsf管理表单上的多对多关系

java - 休息服务在 POJO 中序列化 JSON 请求后如何调用方法?

java - 安卓 : moving bmp leaving a trail ( Surface View and Canvas )

java - 类 : . .. 中的 IllegalArgumentException 属性的 getter 方法:id