所以情况如下:有一个实体需要与字典连接。想象一下以下结构
create table Address (
addressId bigint not null,
addressLine1 varchar(255),
city varchar(255),
country varchar(255),
state varchar(255),
zipCode varchar(255),
primary key (addressId)
)
create table STATES_DICT (
state_code varchar(255),
state_fullname varchar(255),
primary key (state_code)
)
我想将ADDRESS和STATE_DICTIONARY映射到单个实体。
@Entity
@Table(name = "ADDRESS")
public class Address implements Serializable {
@Id
@Column(name = "ADDRESSID")
private int addressId;
@Column(name = "ADDRESSLINE1")
private String addressLine1;
@Column(name = "STATE")
private String state;
//??? annotations
private String fullStateName;
@Column(name = "ZIPCODE")
private String zipCode;
@Column(name = "CITY")
private String city;
@Column(name = "COUNTRY")
private String country;
//... getters and setters
}
对于纯SQL,我将运行
select a.ADDRESSID, a.ADDRESSLINE1, a.CITY, a.ZIPCODE, a.STATE,
d.STATE_FULLNAME, a.COUNTRY
from ADDRESS a, STATES_DICT d where a.STATE = d.STATE_CODE
但我在使用JPA映射时遇到了严重问题。
@ElementCollection
@JoinTable(name="STATES_DICT",
joinColumns=@JoinColumn(name="STATE_CODE", referencedColumnName="STATE"))
@Column(name = "STATE_FULLNAME")
private Collection<String> fullStateName;
下行是 - 映射始终是一对一的,并且收集带来混乱,并且关系更多地是一对一(多对一)而不是一对多。
有什么想法吗?对于一对一映射,是否存在等效的@ElementCollection? 删除@ElementCollection没有帮助。 fullStateName字段应该在ADDRESS列中 - 事实并非如此。
一些说明: *我需要将这两者整合在一个实体中。 *我正在扩展现有的解决方案,需要添加这个字典列 *稍后由一些仅通过基本类型运行的其他服务处理该实体。我宁愿不改变服务,这就是为什么添加@OneToOne关系不是更好的原因
非常感谢
我正在用@SecondaryTable示例扩展这个问题 - 这对我不起作用。
@Entity
@Table(name = "ADDRESS")
@SecondaryTable(name="STATES_DICT",
pkJoinColumns=@PrimaryKeyJoinColumn(columnDefinition="STATE_CODE", referencedColumnName="STATE"))
public class Address implements Serializable {
@Id
@Column(name = "ADDRESSID")
private int addressId;
@Column(name = "ADDRESSLINE1")
private String addressLine1;
@Column(name = "STATE")
private String state;
@Column(table="STATES_DICT", name = "STATE_FULLNAME")
private String fullStateName;
@Column(name = "ZIPCODE")
private String zipCode;
@Column(name = "CITY")
private String city;
@Column(name = "COUNTRY")
private String country;
//... getters and setters
}
这引起了一个令人讨厌的例外: 引起:org.hibernate.AnnotationException:SecondaryTable JoinColumn无法引用非主键
为了记录 - 我找不到办法做到这一点(并假设它根本不是应该这样做的方式)。我已经使用关系注释(@ManyToOne,@ OneToOne)和@JoinColumn - 所以正确的方法。我已经调整了进一步的处理逻辑来处理@JoinColumn注释,就像它使用@Column一样。它奏效了。
进一步处理是一种安全功能,它根据用户角色和原始数据库列名来抑制值。这就是为什么我坚持使用@Column注释
非常重要答案 0 :(得分:1)
使用
来自user2601805的回答是正确的@PrimaryKeyJoinColumn(name="STATE_CODE", referencedColumnName="STATE")
在你的情况下,这应该足够了,因为你想要的只是STATES_DICT的属性。
我还询问了一个与JPA有关的问题,该问题显示了使用@SecondaryTable和@Embeddable来实现与@ElementCollection相似但是对于@OneToOne的一个例子
答案 1 :(得分:0)
您应该能够创建映射关系的@Embeddable State类,但提供委托方法以将状态名称公开为属性。这会完成你想要做的事吗?
答案 2 :(得分:0)
在@pkJoinColumns
中你应该使用:
@PrimaryKeyJoinColumn(name="STATE_CODE", referencedColumnName="STATE")
我有同样的问题,你使用@SecondaryTable
的提示解决了我的问题。有关详细信息,请参阅Mapping one entity to several tables。