使用MYSQL表结构创建JPA映射时遇到问题

时间:2019-07-08 20:12:24

标签: java hibernate jpa

我有一张表,该表对一个国家可以支持多种音高类型的关系进行建模。因此,美国支持音高类型1、2和3。MX支持音高类型2、3和4。

pitch_type表是一个简单的键值,其pitch_type_id引用了字符串值。将类型与国家/地区代码连接起来的表在这里:

CREATE TABLE `country_pitch` (
  `country_pitch_id` INT NOT NULL AUTO_INCREMENT,
  `country_code` VARCHAR(2) NOT NULL,
  `pitch_type_id` INT NOT NULL,
  PRIMARY KEY (`country_pitch_id`),
  INDEX `fk_country_code_to_pitch_type_id_idx` (`pitch_type_id` ASC),
  CONSTRAINT `fk_country_code_to_pitch_type_id`
    FOREIGN KEY (`pitch_type_id`)
    REFERENCES `pitch_type` (`pitch_type_id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION);

收益:

---------------------------------------------------
| country_pitch_id | country_code | pitch_type_id |
---------------------------------------------------
| 1                | us           | 1             |
| 2                | us           | 2             |
| 3                | us           | 3             |
| 4                | mx           | 2             |
| 5                | mx           | 3             |
| 6                | mx           | 4             |
---------------------------------------------------

country_pitch_id未使用,重要的概念是将国家/地区代码与其关联的pitch_type相匹配。

我认为,一个国家可以具有多个音调类型,而一个音调类型可以属于多个国家,这将最好用ManyToMany关系来表示。我的目标是在类似于以下内容的POJO中对此进行建模:


/**
 * For a given market, US, CA, MX, etc, identify the available reach
 * generation curve types
 */
@Entity(name = "country_pitch")
@Data
public class CountryPitchTypes {
    public CountryPitchTypes() {}

    @Column(name = "country_code")
    private String countryCode;

    @ElementCollection
    @Convert(converter = PitchTypeConverter.class)
    private List<PitchType> pitchTypes;
}

,但是该映射无法立即使用,因为我试图将联接表映射到该实体,因此出现Unknown column错误。您能否指导我将pojo映射到具有相关列表的单个pojo,是对pojo的适当补充?

我觉得@JoinTable批注对于某种分组是必需的,但不确定如何配置它。归根结底,我正尝试将country_pitch表映射到CountryPitchTypes类,并按国家/地区代码对所有音高类型进行分组。

国家代码不属于我们的数据库,顺便说一句。也就是说,没有countries表,country_id num指向2个字母的country_code。

2 个答案:

答案 0 :(得分:0)

在这种情况下,注释ManyToMany不正确。这意味着许多CountryPitchTypes映射到许多PitchType。您需要的是OneToMany。

答案 1 :(得分:0)

由于国家/地区代码可以映射到n个音调类型,而单个音调类型可以映射到n个国家/地区 所以我们有一个ManyToMany关系

与使用country_pitch_id一样,您有2种方式来实现ManyToMany关系,要么使用2个关系列使用复合主键,要么将单个主ID与2个关系列一起使用,所以遵循所有此实体如下:

@Entity(name = "country_pitch")
@Data
public class CountryPitchTypes {
    public CountryPitchTypes() {}

    @Id
    @Column(name = "country_pitch_id", updatable = false, nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY) // or whatever strategy you see good
    private Long countryPitchId

    @Column(name = "country_code")
    private String countryCode;

    @JoinColumn(name = "pitch_type_id", referencedColumnName = "pitch_type_id")
    @ManyToOne
    @Convert(converter = PitchTypeConverter.class)
    private PitchType pitchType;
}

现在您可以去做

SELECT cpt.pitchType from CountryPitchTypes cpt group by cpt.countryCode;

旁注 请记住,ManyToMany关系基本上是在创建第三个表country_pitch,其中您具有另一个表pitch_type的另一个表PitchType的ManyToOne字段,因此您现在可以更新CountryPitch实体以使OneToMany country_pitch_id,但无论如何您都不会使用它,因此一种关系就足够了,这个BTW是所谓的单向关系

在JPA中,当第三个表没有任何额外的列ansible --version ansible 2.8.0 config file = /etc/ansible/ansible.cfg configured module search path = [u'/home/kjames/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python2.7/site-packages/ansible executable location = /usr/bin/ansible python version = 2.7.5 (default, Apr 9 2019, 14:30:50) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] cat /etc/os-release NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)" 仅使用2个关系列时,使用@ManyToMany批注,通过这种方式,JPA可以隐式理解该表用于执行ManyToMany关系,然后可以使用@在不创建第三个实体的情况下,对相关实体进行ManyToMany。