基本类型的一对一映射,在Hibernate中成为单个类

Jak*_*cki 5 java annotations hibernate jpa

所以情况如下:有一个实体需要与字典连接.想象一下以下结构

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)
)
Run Code Online (Sandbox Code Playgroud)

我想将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
}
Run Code Online (Sandbox Code Playgroud)

对于纯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
Run Code Online (Sandbox Code Playgroud)

但我在使用JPA映射时遇到了严重问题.

  1. 我不能使用@SecondaryTable,因为表没有按主键映射
  2. 我能得到的最好的是:
    @ElementCollection
    @JoinTable(name="STATES_DICT", 
            joinColumns=@JoinColumn(name="STATE_CODE", referencedColumnName="STATE"))
    @Column(name = "STATE_FULLNAME")
    private Collection<String> fullStateName;
Run Code Online (Sandbox Code Playgroud)

缺点是 - 映射始终是一对一的,而集合带来了混乱,而且这种关系更多地是一对一(多对一)而不是一对多.

有任何想法吗?对于一对一映射,是否存在等效的@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
}
Run Code Online (Sandbox Code Playgroud)

这引起了一个令人讨厌的异常:引起:org.hibernate.AnnotationException:SecondaryTable JoinColumn无法引用非主键


为了记录 - 我找不到办法做到这一点(并假设它根本不是它应该做的方式).我已经使用关系注释(@ManyToOne,@ OneToOne)和@JoinColumn - 所以正确的方法.我已经调整了进一步的处理逻辑来处理@JoinColumn注释,就像它使用@Column一样.有效.

进一步处理是一种安全功能,它根据用户角色和原始数据库列名来抑制值.这就是为什么我坚持@Column注释是如此重要

小智 1

用户2601805的回答是正确的

@PrimaryKeyJoinColumn(name="STATE_CODE", referencedColumnName="STATE")
Run Code Online (Sandbox Code Playgroud)

就您而言,这应该足够了,因为您想要的只是 STATES_DICT 的属性。

我还问了一个与 JPA 相关的问题,该问题显示了使用 @SecondaryTable 和 @Embeddable 来实现类似于 @ElementCollection 但用于 @OneToOne 的示例

另请参阅此博客,例如http://www.bagdemir.com/2013/03/03/mapping-embeddable-objects-whichve-no-identities-using-multiple-tables-with-jpahibernate/