ERROR当使用相同的连接表引用关联实体的子类时,具有该名称[user_address]的表已与实体关联

Ton*_*dro 9 java hibernate jpa

使用Spring Boot启动器,我试图创建一个涉及具有多个地址字段的用户的简单示例项目.我正在尝试使用@DiscriminatorColumn和@DiscriminatorValue来区分用户可能拥有的不同类型的地址.

这是我项目中表格的缩写示例:

CREATE TABLE user ( id INT AUTO_INCREMENT);
CREATE TABLE user_address ( user_id INT, address_id INT);
CREATE TABLE address ( id INT AUTO_INCREMENT, TYPE VARCHAR(31));
Run Code Online (Sandbox Code Playgroud)

以下是我要加入的课程:

@Entity
@DiscriminatorColumn(name = "type")
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String type;
}

@Entity
@DiscriminatorValue("HOME")
public class HomeAddress extends Address {}

@Entity
@DiscriminatorValue("CURRENT")
public class CurrentAddress extends Address{}

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String type;

    @OneToOne
    @JoinTable(
        name = "user_address",
        joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
        inverseJoinColumns = {@JoinColumn(name = "address_id", referencedColumnName = "id")}
    )
    private HomeAddress homeAddress;

    @OneToOne
    @JoinTable(
        name = "user_address",
        joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
        inverseJoinColumns = {@JoinColumn(name = "address_id", referencedColumnName = "id")}
    )
    private CurrentAddress currentAddress;

}
Run Code Online (Sandbox Code Playgroud)

我已经尝试过替换@OneToOne,@OneToMany但它仍然不起作用.

我希望能够做到这一点的原因是我正在考虑将地址与其他实体相关联.例如,订单的ShippingAddress或建筑物的LocationAddress等.

这是错误的转储:

Caused by: org.hibernate.boot.spi.InFlightMetadataCollector$DuplicateSecondaryTableException: Table with that name [user_address] already associated with entity
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl$EntityTableXrefImpl.addSecondaryTable(InFlightMetadataCollectorImpl.java:1420) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.cfg.annotations.EntityBinder.addJoin(EntityBinder.java:972) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.cfg.annotations.EntityBinder.addJoin(EntityBinder.java:868) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.cfg.ClassPropertyHolder.addJoin(ClassPropertyHolder.java:207) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1792) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:904) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:731) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:245) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:222) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:265) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:847) ~[hibernate-entitymanager-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:874) ~[hibernate-entitymanager-5.0.9.Final.jar:5.0.9.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:338) ~[spring-orm-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373) ~[spring-orm-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362) ~[spring-orm-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    ... 16 common frames omitted
Run Code Online (Sandbox Code Playgroud)

dav*_*xxx 1

你的错误是:

导致:org.hibernate.boot.spi.InFlightMetadataCollector$DuplicateSecondaryTableException:具有该名称 [user_address] 的表已与实体关联

您忘记了@Inheritance注释。我想您对所有地址类使用一个表。因此,您应该明确您想要使用SINGLE_TABLE处理 OOP->SQL 映射的策略。它是默认使用的,但您可以精确它,因为更具可读性。

将其添加到超类实体的类声明中: @Inheritance(strategy = InheritanceType.SINGLE_TABLE)

这样 :

@Entity
@DiscriminatorColumn(name = "type")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String type;
}
Run Code Online (Sandbox Code Playgroud)

编辑 :

user_address在实体的多个关系中用作可连接的User。Hibernate给人的印象是它不接受它。

如果您使用单一关系,您将失去对地址进行分类的好处。
如果您可以更改架构,则可以删除联接表并在地址中添加 fk 来指定 userId。抱歉,我没有其他线索。