【问题标题】:"Provided id of the wrong type for" error when using save() method of an @Embeddable class使用 @Embeddable 类的 save() 方法时出现“提供了错误类型的 id”错误
【发布时间】:2021-10-08 02:01:47
【问题描述】:

我仍在进行我的第一个单独的弹簧靴项目。假设它是一个使用 MariaDB 示例数据库 Nation 的 Rest API。有一个 country_languages 表,它接收两个外键,这两个外键也是主键,并且有另一个常规字段。第一个外键是国家表中的 id,第二个是语言表中的 id。当我使用 save() 方法创建一个新元组时,出现此错误:

org.springframework.dao.InvalidDataAccessApiUsageException: Provided id of the wrong type for class me.givo.nationdbapiproject.model.CountryLanguages. Expected: class me.givo.nationdbapiproject.model.CountryLanguagesId, got class java.lang.Integer; nested exception is java.lang.IllegalArgumentException: Provided id of the wrong type for class me.givo.nationdbapiproject.model.CountryLanguages. Expected: class me.givo.nationdbapiproject.model.CountryLanguagesId, got class java.lang.Integer

这是来自MariaDB example 的 country_languages 表:

create table country_languages(
    country_id int,
    language_id int,
    official boolean not null,
    primary key (country_id, language_id),
    foreign key(country_id) 
    references countries(country_id),
    foreign key(language_id) 
    references languages(language_id)
);

我正在使用@Embeddable 类 CountryLanguagesId 来制作我在此reference 中找到的复合键。

@Embeddable
public class CountryLanguagesId implements Serializable {
    @Column(name = "country_id")
    private Integer countryId;
    @Column(name = "language_id")
    private Integer languageId;

    public CountryLanguagesId() {
    }

    public CountryLanguagesId(Integer countryId, Integer languageId) {
        this.countryId = countryId;
        this.languageId = languageId;
    }
// + getters and setters

之后,我为 country_languages 表及其存储库创建了实体:

@Entity
@Table(name = "country_languages")
public class CountryLanguages {

    @EmbeddedId
    CountryLanguagesId countryLanguagesId = new CountryLanguagesId();

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @MapsId("countryId")
    @JoinColumn(name = "country_id")
    private Countries countries;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @MapsId("languageId")
    @JoinColumn(name = "language_id")
    private Languages languages;

    @Column(name = "official", length = 1, nullable = false)
    private Integer official;

    public CountryLanguages() {
    }

    public CountryLanguages(Countries country, Languages language, Integer official) {
        this.countries = country;
        this.languages = language;
        this.official = official;
    }
// + getters and setters
@Repository
public interface ICountryLanguagesJpaRepository extends JpaRepository<CountryLanguages, Integer> {

}

有国家和语言实体:

@Entity
@Table(name = "countries")
public class Countries {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "country_id", length = 11, nullable = false)
    private Integer countryId;

    @Column(name = "name", length = 50, nullable = true)
    private String name;

    @Column(name = "area", nullable = false)
    private BigDecimal area;

    @Column(name = "national_day", nullable = true)
    private java.sql.Date nationalDay;

    @Column(name = "country_code2", length = 2, nullable = false)
    private String countryCode2;

    @Column(name = "country_code3", length = 3, nullable = false)
    private String countryCode3;

    @OneToMany(mappedBy = "countries", cascade = CascadeType.ALL)
    private Set<CountryLanguages> countryLanguages;

    public Countries() {
    }

    public Countries(String name, BigDecimal area, Date nationalDay, String countryCode2, String countryCode3) {
        this.name = name;
        this.area = area;
        this.nationalDay = nationalDay;
        this.countryCode2 = countryCode2;
        this.countryCode3 = countryCode3;
    }
@Entity
@Table(name = "languages")
public class Languages {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "language_id", length = 11, nullable = false)
    private Integer languageId;

    @Column(name = "language", length = 50, nullable = false)
    private String language;

    @OneToMany(mappedBy = "languages", cascade = CascadeType.ALL)
    private Set<CountryLanguages> countryLanguages;

    public Languages() {
    }

    public Languages(String language) {
        this.language = language;
    }

    public Integer getLanguageId() {
        return languageId;
    }

这些是我收到错误时所做的条目:

@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
public class ICountryLanguagesJpaRepositoryTest {

    @Autowired
    private ICountriesJpaRepository countries;
    @Autowired
    private ILanguagesJpaRepository languages;
    @Autowired
    private ICountryLanguagesJpaRepository repository;

    @Test
    public void shouldSaveAndRemoveContinents() {

        Countries patu = new Countries("Patu", new BigDecimal(67822.34), new Date(12321233232L), "PU", "PTU");
        countries.save(patu);

        Languages patuano = new Languages("Patuano");
        languages.save(patuano);

        CountryLanguages pLanguages = new CountryLanguages(patu, patuano, 0);

        repository.save(pLanguages);

        assertEquals(1, repository.findAll().size());

        System.out.println(repository.findAll());

        repository.deleteById(1);

        assertEquals(0, repository.findAll().size());

    }

我正在使用 H2 数据库执行此操作。这是完整的debug console output。抱歉,由于字符限制,无法在此处粘贴。

谢谢!

【问题讨论】:

    标签: java spring spring-boot hibernate jpa


    【解决方案1】:

    您的存储库定义错误。您应该将可嵌入类型指定为主键类型:

    @Repository
    public interface ICountryLanguagesJpaRepository extends JpaRepository<CountryLanguages, CountryLanguagesId> {
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-05
      • 2012-06-04
      • 1970-01-01
      • 2012-03-17
      • 1970-01-01
      • 2019-01-05
      • 2015-01-12
      • 1970-01-01
      相关资源
      最近更新 更多