我有两个实体:
表示来自设备的原始消息的raw device message
表示解析后消息的TagDetail
TagDetail可能与RawDeviceMessage关联,也可能与RawDeviceMessage无关,因为它可以直接创建,而无需解析原始消息。因此,我在RawDeviceMessage和TagDetail之间有一个可选的双向单点关系。
在数据库中,我有以下表:
原始设备消息(id+其他列)
标记详细信息(id+其他列)
tag_detail_has_raw_device_message(tag_detail_id,raw_device_message_id):此表是一个JoinTable,具有适当的SQL约束和外键,用于在数据库级别强制实现OneToOne关系。
我已经这样映射了我的Java类:
RawDeviceMessage消息
@Entity
@Table(name = "raw_device_message")
public class RawDeviceMessage implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", unique = true, updatable = false, nullable = false)
private Long id;
@OneToOne(mappedBy = "rawDeviceMessage", fetch = FetchType.LAZY)
private TagDetail tagDetail;
public RawDeviceMessage(){}
public Long getId(){...}
public void setId(final Long id){...}
public TagDetail getTagDetail(){...}
public RawDeviceMessage setTagDetail(TagDetail tagDetail){...}
}
标记详细信息
@Entity
@Table(name = "tag_detail")
public class TagDetail implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", unique = true, updatable = false, nullable = false)
private Long id;
@OneToOne(fetch = FetchType.EAGER, cascade = { CascadeType.REFRESH, CascadeType.MERGE })
@JoinTable(
name="tag_detail_has_raw_device_message",
joinColumns=@JoinColumn(name="tag_detail_id"),
inverseJoinColumns=@JoinColumn(name="raw_device_message_id"))
private RawDeviceMessage rawDeviceMessage;
public TagDetail() {}
public Long getId(){...}
public void setId(final Long id){...}
public RawDeviceMessage getRawDeviceMessage(){...}
public void setRawDeviceMessage(RawDeviceMessage rawDeviceMessage){...}
}
问题
我的问题是,在对RawDeviceMessage资源执行find all时,Hibernate生成了错误的SQL查询:
SELECT rawdevicem0_.id AS id1_15_,
rawdevicem0_2_.tag_detail_id AS tag_deta0_37_,
FROM raw_device_message rawdevicem0_
LEFT OUTER JOIN tag_detail_has_raw_device_message rawdevicem0_2_ ON rawdevicem0_.id=rawdevicem0_2_.tag_detail_id
CROSS JOIN tag_detail tagdetail1_
LEFT OUTER JOIN tag_detail_has_raw_device_message tagdetail1_1_ ON tagdetail1_.id=tagdetail1_1_.tag_detail_id
WHERE rawdevicem0_2_.tag_detail_id=tagdetail1_.id
ORDER BY rawdevicem0_.id ASC
如您所见,在第一个
LEFT OUTER JOIN
中,连接条件是rawdevicem0_.id=rawdevicem0_2_.tag_detail_id
它试图将
raw_device_message.id
与tag_detail_has_raw_device_message.tag_detail_id
连接起来,这毫无意义,而且会弄乱所有结果。相反,连接条件应该是,
rawdevicem0_.id=rawdevicem0_2_.raw_device_message_id
此条件将与
raw_device_message.id
正确连接我已经缩短了hibernate生成的查询以删除所有不相关的字段,但是在生成的查询中没有列
tag_detail_has_raw_device_message.raw_device_message_id
,因此肯定有问题。这是一个休眠错误还是我的映射错误?
最佳答案
如果tag_detail_has_raw_device_消息表的目的只是链接这两个表,则可以删除它。你可以一对一,只有两张桌子。
这里有更多细节-
Setting up a One To ManyJoins Against a Bridge Table using JPA
但是,如果您希望有一个中间映射表,因为它有一些关于该关系的附加信息,那么这里有更多详细信息。
http://what-when-how.com/hibernate/advanced-entity-association-mappings-hibernate/