当我添加第二个ManyToMany关系时,为什么我会得到此无法确定`...Project`推荐的JdbcType?

问题描述 投票:0回答:1

我正在我的类上使用 SpringDataJPA 和 Hibernate 映射开发 Spring Boot 应用程序,但遇到以下问题。

首先我有这个Project实体类:

@Entity
@Table(name = "project")
public class Project {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;

    @Column(name = "project_name", nullable = false)
    private String projectName;
    
    @Column(name = "code", nullable = false)
    private String projectCode;

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

    @Column(name = "start_date", nullable = false)
    @Temporal(TemporalType.DATE)
    private LocalDate startDate;

    @Column(name = "end_date", nullable = false)
    @Temporal(TemporalType.DATE)
    private LocalDate endDate;

    @Column(name = "budget", nullable = false, precision = 10, scale = 2)
    private BigDecimal budget;

    @ManyToOne
    @JoinColumn(name = "client_id_fk", referencedColumnName = "id", nullable = false)
    private Client client;
    
    
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(
        name = "project_supplier",
        joinColumns = @JoinColumn(name = "project_id"),
        inverseJoinColumns = @JoinColumn(name = "supplier_id")
    )
    private Set<Supplier> suppliers = new HashSet<>();
   

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getProjectName() {
        return projectName;
    }
    
    

    public String getProjectCode() {
        return projectCode;
    }

    public void setProjectCode(String projectCode) {
        this.projectCode = projectCode;
    }

    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public LocalDate getStartDate() {
        return startDate;
    }

    public void setStartDate(LocalDate startDate) {
        this.startDate = startDate;
    }

    public LocalDate getEndDate() {
        return endDate;
    }

    public void setEndDate(LocalDate endDate) {
        this.endDate = endDate;
    }

    public BigDecimal getBudget() {
        return budget;
    }

    public void setBudget(BigDecimal budget) {
        this.budget = budget;
    }

    public Client getClient() {
        return client;
    }

    public void setClient(Client client) {
        this.client = client;
    }
    

    public Set<Supplier> getSuppliers() {
        return suppliers;
    }

    public void setSuppliers(Set<Supplier> suppliers) {
        this.suppliers = suppliers;
    }
    

    @Override
    public String toString() {
        return "Project [id=" + id + ", projectName=" + projectName + ", description=" + description + ", startDate="
                + startDate + ", endDate=" + endDate + ", budget=" + budget + ", client=" + client + "]";
    }
    
      
}

如您所见,它包含与 Supplier 实体的多对多关系:

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
    name = "project_supplier",
    joinColumns = @JoinColumn(name = "project_id"),
    inverseJoinColumns = @JoinColumn(name = "supplier_id")
)
private Set<Supplier> suppliers = new HashSet<>();

这是我的project_supplier关系表:

p”寻求帮助。

gestionale_interno_db=# \d project_suplier
Did not find any relation named "project_suplier".
gestionale_interno_db=# \d project_supplier
                            Table "public.project_supplier"
   Column    |     Type      | Collation | Nullable |             Default              
-------------+---------------+-----------+----------+----------------------------------
 id          | bigint        |           | not null | generated by default as identity
 project_id  | bigint        |           | not null | 
 supplier_id | bigint        |           | not null | 
 notes       | text          |           |          | 
 daily_rate  | numeric(10,2) |           | not null | 
Indexes:
    "project_supplier_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "project_supplier_project_id_fkey" FOREIGN KEY (project_id) REFERENCES project(id)
    "project_supplier_supplier_id_fkey" FOREIGN KEY (supplier_id) REFERENCES supplier(id)

这个效果很好。当我将等效的 ManyToMany 关系引入到我的 Supplier 实体类中时,就会出现问题:

@Entity
@Table(name = "supplier")
public class Supplier {

    private long id;
    private String name;
    private String vatNumber;
    private String address;
    private String email;
    
    
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(
        name = "project_supplier",
        joinColumns = @JoinColumn(name = "supplier_id"),
        inverseJoinColumns = @JoinColumn(name = "project_id")
    )
    private Set<Project> projects = new HashSet<>();
    
    
    public Supplier() {
        super();
    }

    public Supplier(String name, String vatNumber, String address, String email) {
        super();
        this.name = name;
        this.vatNumber = vatNumber;
        this.address = address;
        this.email = email;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    @Column(name = "name", nullable = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(name = "vat_number", nullable = false)
    public String getVatNumber() {
        return vatNumber;
    }

    public void setVatNumber(String vatNumber) {
        this.vatNumber = vatNumber;
    }

    @Column(name = "address", nullable = false)
    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
    
    

    public Set<Project> getProjects() {
        return projects;
    }

    public void setProjects(Set<Project> projects) {
        this.projects = projects;
    }

    @Override
    public String toString() {
        return "Supplier [id=" + id + ", name=" + name + ", vatNumber=" + vatNumber + ", address=" + address
                + ", email=" + email + ", projects=" + projects + "]";
    }
    
}

事实上,当我将此关系添加到第二个实体类中时:

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
    name = "project_supplier",
    joinColumns = @JoinColumn(name = "supplier_id"),
    inverseJoinColumns = @JoinColumn(name = "project_id")
)
private Set<Project> projects = new HashSet<>();

运行我的应用程序时出现此异常:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Could not determine recommended JdbcType for `com.fivebits.gestionale.model.entity.Project`
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1770) ~[spring-beans-6.0.12.jar:6.0.12]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598) ~[spring-beans-6.0.12.jar:6.0.12]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[spring-beans-6.0.12.jar:6.0.12]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.0.12.jar:6.0.12]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.12.jar:6.0.12]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.0.12.jar:6.0.12]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.0.12.jar:6.0.12]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1158) ~[spring-context-6.0.12.jar:6.0.12]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) ~[spring-context-6.0.12.jar:6.0.12]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) ~[spring-context-6.0.12.jar:6.0.12]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.1.4.jar:3.1.4]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) ~[spring-boot-3.1.4.jar:3.1.4]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.1.4.jar:3.1.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-3.1.4.jar:3.1.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) ~[spring-boot-3.1.4.jar:3.1.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) ~[spring-boot-3.1.4.jar:3.1.4]
    at com.fivebits.gestionale.GestionaleInternoApplication.main(GestionaleInternoApplication.java:10) ~[classes/:na]
Caused by: org.hibernate.type.descriptor.java.spi.JdbcTypeRecommendationException: Could not determine recommended JdbcType for `com.fivebits.gestionale.model.entity.Project`
    at org.hibernate.type.descriptor.java.spi.UnknownBasicJavaType.getRecommendedJdbcType(UnknownBasicJavaType.java:37) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
    at org.hibernate.type.descriptor.java.spi.BasicCollectionJavaType.getRecommendedJdbcType(BasicCollectionJavaType.java:74) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
    at org.hibernate.boot.model.process.internal.InferredBasicValueResolver.from(InferredBasicValueResolver.java:222) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
    at org.hibernate.mapping.BasicValue.buildResolution(BasicValue.java:480) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
    at org.hibernate.mapping.BasicValue.resolve(BasicValue.java:310) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
    at org.hibernate.mapping.BasicValue.resolve(BasicValue.java:300) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.lambda$processValueResolvers$4(InFlightMetadataCollectorImpl.java:1855) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
    at java.base/java.util.ArrayList.removeIf(ArrayList.java:1682) ~[na:na]
    at java.base/java.util.ArrayList.removeIf(ArrayList.java:1660) ~[na:na]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processValueResolvers(InFlightMetadataCollectorImpl.java:1854) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1840) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:331) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1380) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1451) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75) ~[spring-orm-6.0.12.jar:6.0.12]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376) ~[spring-orm-6.0.12.jar:6.0.12]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-6.0.12.jar:6.0.12]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-6.0.12.jar:6.0.12]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352) ~[spring-orm-6.0.12.jar:6.0.12]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1817) ~[spring-beans-6.0.12.jar:6.0.12]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1766) ~[spring-beans-6.0.12.jar:6.0.12]
    ... 16 common frames omitted

为什么会出现这个错误?怎么了?我该如何解决它?

java spring spring-boot hibernate hibernate-mapping
1个回答
0
投票

根据项目实体中的 JPA 标准,无需再次指定父关系,只需:

@ManyToMany(mappedBy = "suppliers")    
private Set<Project> projects = new HashSet<>();

在这里您可以找到详尽的指南:JPA 中的多对多关系

希望对你有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.