【问题标题】:Jpa ManytoMany issue with Spring BootSpring Boot 的 Jpa ManytoMany 问题
【发布时间】:2017-02-02 20:16:28
【问题描述】:

我有一个 postgres 数据库,我正在尝试使用 Spring Boot 制作一个简单的 REST 服务。我的 jpa 多对多关系有问题。

个人实体:

@Entity
@Table(name = "person", schema = "persons")
public class Person implements Serializable {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;

@Column(nullable = false)
private String name;

@Column(nullable = false)
private String email;

@Column
private Integer age;

@ManyToOne
@JoinColumn(name = "country_id", referencedColumnName = "id")
private Country countryOfBirth;

@ManyToMany
@JoinTable(
        name="persons_countries_residence",
        joinColumns=@JoinColumn(name="person_id", referencedColumnName="id"),
        inverseJoinColumns=@JoinColumn(name="country_id", referencedColumnName="id"))
private List<Country> countriesOfResidence;

// getters and setters and to String method overriden
}

国家实体:

@Entity
@Table(name = "country", schema = "persons")
public class Country implements Serializable {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;

@Column(name = "country_name")
private String name;

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

 // getters and setters and to String method overriden
}

postgres 架构如下:

人员表:

CREATE TABLE persons.person
(
  id serial NOT NULL,
  name character varying(50) NOT NULL,
  email character varying(40) NOT NULL,
  age integer,
  country_id serial NOT NULL,
  CONSTRAINT id PRIMARY KEY (id),
  CONSTRAINT country_id FOREIGN KEY (id)
  REFERENCES persons.country (id) MATCH SIMPLE
  ON UPDATE NO ACTION ON DELETE NO ACTION
 )

国家表:

CREATE TABLE persons.country
(
  id serial NOT NULL,
  country_name character varying(45) NOT NULL,
  country_code character varying(10) NOT NULL,
  CONSTRAINT country_id PRIMARY KEY (id)
)

加入表:

CREATE TABLE persons.persons_countries_residence
(
  person_id integer NOT NULL,
  country_id integer NOT NULL,
  CONSTRAINT person_country_id PRIMARY KEY (person_id, country_id),
  CONSTRAINT persons_countries_residence_country_id_fkey FOREIGN KEY (country_id)
  REFERENCES persons.country (id) MATCH SIMPLE
  ON UPDATE CASCADE ON DELETE NO ACTION,
  CONSTRAINT persons_countries_residence_person_id_fkey FOREIGN KEY (person_id)
  REFERENCES persons.person (id) MATCH SIMPLE
  ON UPDATE CASCADE ON DELETE CASCADE
 )

当我进行 HTTP 方法调用时,我没有得到居住国家/地区。

服务代码:

 @RequestMapping(method = RequestMethod.GET, produces =   {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
 public List<Person> getAllPersons() {
     retutn jpaPersonRepository.findAll();
 }

任何帮助表示赞赏。

【问题讨论】:

    标签: spring postgresql hibernate jpa


    【解决方案1】:

    你的意思是国家列表是空的吗? @ManyToMany 关联默认是延迟加载的,您需要启用 Eager-fetching 才能立即工作。

    @ManyToMany(fetch = FetchType.EAGER)
    

    【讨论】:

    • 是的,国家列表为空。但是,所有其他字段都有值。设置fetch = FetchType.EAGER 并没有解决这个问题。 (在persons.persons_countries_residence 表中,我为存在的个人和国家设置了两个现有ID)。
    【解决方案2】:

    也许,你需要在连接表名中指定一个模式名:

    @JoinTable(
            name="persons_countries_residence", schema="persons",
            joinColumns=@JoinColumn(name="person_id", referencedColumnName="id"),
            inverseJoinColumns=@JoinColumn(name="country_id", referencedColumnName="id"))
    

    【讨论】:

    • 如果我这样做我会得到异常:org.postgresql.util.PSQLException: ERROR: relation "persons_persons_countries_residence" does not exist
    【解决方案3】:

    解决办法是这样的:

      @ManyToMany
      @JoinTable(
            name="persons_countries_residence", schema = "persons",
            joinColumns=@JoinColumn(name="person_id", referencedColumnName="id"),
            inverseJoinColumns=@JoinColumn(name="country_id", referencedColumnName="id"))
    private List<Country> countriesOfResidence;
    

    架构也必须在 @JoinTable 注释中指定。

    【讨论】:

      【解决方案4】:

      更新您的 Country 类代码,如:

      @Entity
      @Table(name = "country", schema = "persons")
      public class Country implements Serializable {
      @Id
      @GeneratedValue(strategy= GenerationType.IDENTITY)
      private Integer id;
      
      @Column(name = "country_name")
      private String name;
      
      @Column(name = "country_code")
      private String code;
      
      @ManyToMany(mappedBy = "countriesOfResidence")
      private List<Person> persons;
      
       // getters and setters and to String method overriden
      }
      

      虽然 ManyToMany 关系在 数据库,对象模型可以选择是否在两者中都映射 方向,以及它将被映射到哪个方向。如果您选择 要在两个方向上映射关系,则必须是一个方向 定义为所有者,另一个必须使用 mappedBy 属性来 定义它的映射。这也避免了复制 JoinTable 两个地方的信息。

      【讨论】:

        猜你喜欢
        • 2020-02-04
        • 2017-12-12
        • 1970-01-01
        • 2011-02-09
        • 2020-01-04
        • 1970-01-01
        • 1970-01-01
        • 2021-11-06
        • 2019-06-16
        相关资源
        最近更新 更多