且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

处理实体继承Spring Boot

更新时间:2022-12-18 11:25:51

您的问题出在JPA要求的"Discriminator"列中.您正在使用@Inheritance批注,并且默认情况下将使用InheritanceType.SINGLE_TABLE策略.这意味着:

Your issue is with the "Discriminator" column that JPA requires. You are using the @Inheritance annotation and by default that will use the InheritanceType.SINGLE_TABLE strategy. That means the following:

  1. 您继承的实体Person​​和Company将进入一个表.
  2. JPA将需要一个鉴别器来区分实体类型.
  1. Your inherited entities Person and Company will go into a single table.
  2. JPA will require a Discriminator to differentiate between entity types.

为了使它适用于您的用例,我做了以下工作:

I did the following to make it work for your use case:

实体:

Entities:

@Inheritance
@Entity
@Table(name = "user_table")
public abstract class User {

    @Id
    private long id;

    @NotNull
    @Column
    private String email;

    public long getId() {
        return id;
    }

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

    public String getEmail() {
        return email;
    }

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

@Entity
public class Company  extends User {

    @Column(name = "company_name")
    private String companyName;

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }
}

@Entity
public class Person extends User {

    @Column
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

数据库架构:

DB Schema:

-- user table
create table user_table (
  id BIGINT         NOT NULL PRIMARY KEY,
    email             VARCHAR(50) NOT NULL,
    age               INT,
    company_name      VARCHAR(50),
    dtype             VARCHAR(80) -- Discriminator
);

一些测试数据:

Some test data:

insert into user_table(id, dtype, age, email) values
(1,'Person', 25, 'john.doe@email.com'),
(2,'Person',22, 'jane.doe@email.com');

insert into user_table(id, dtype, company_name, email) values
(3,'Company','Acme Consultants', 'acme@company.com'),
(4,'Company', 'Foo Consultants', 'foo@company.com');

存储库:

Repositories:

@NoRepositoryBean
public interface UserBaseRepository<T extends User> extends CrudRepository<T, Long> {

    T findByEmail(String email);
}

@Transactional
public interface PersonRepository extends UserBaseRepository<Person> {

}

@Transactional
public interface CompanyRepository extends UserBaseRepository<Company> {

}

JUnit测试:

JUnit Tests:

public class MultiRepositoryTest extends BaseWebAppContextTest {

    @Autowired
    private PersonRepository personRepository;

    @Autowired
    private CompanyRepository companyRepository;

    @Test
    public void testGetPersons() {
        List<Person> target = new ArrayList<>();
        personRepository.findAll().forEach(target::add);
        Assert.assertEquals(2, target.size());
    }
    @Test
    public void testGetCompanies() {
        List<Company> target = new ArrayList<>();
        companyRepository.findAll().forEach(target::add);
        Assert.assertEquals(2, target.size());
    }

}

以上测试通过.这表明JPA现在可以正确使用鉴别符来检索所需的记录.

The above tests pass. That indicates JPA now utilizes the discriminator correctly to retrieve the required records.

有关您的问题的JPA相关理论,请参见此链接.

For JPA related theory for your question, see this link.