处理实体继承spring boot

处理实体继承spring boot,spring,spring-boot,jpa,spring-data-jpa,spring-data,Spring,Spring Boot,Jpa,Spring Data Jpa,Spring Data,我用这个来处理实体继承。我有扩展用户实体的个人和公司实体 @Entity @Inheritance public abstract class User { @Id private long id; @NotNull private String email; // getters and settres } @Entity public class Person extends User { private int age; // getters and settres and o

我用这个来处理实体继承。我有扩展用户实体的个人和公司实体

@Entity
@Inheritance
public abstract class User { 

@Id
private long id;

@NotNull
private String email;

// getters and settres
}

@Entity
public class Person extends User { 
private int age;
// getters and settres and other attributs
}

@Entity
public class Company extends User { 
private String companyName;
// getters and settres and other attribut
}
然后是UserRpository、PersonRepository和扩展UserBaseRepository的公司存储库

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

public T findByEmail(String email);

}

@Transactional
public interface UserRepository extends UserBaseRepository<User> { }

@Transactional
public interface PersonRepository extends UserBaseRepository<Person> { }

@Transactional
public interface CompanyRepository extends UserBaseRepository<Company> { }
@NoRepositoryBean
公共接口UserBaseRepository
积垢沉积{
公共T findByEmail(字符串电子邮件);
}
@交易的
公共接口UserRepository扩展了UserBaseRepository{}
@交易的
公共接口PersonRepository扩展了UserBaseRepository{}
@交易的
公共接口CompanyRepository扩展了UserBaseRepository{}
问题是调用personRepository.findAll()获取所有人员时,结果我也得到了公司。

您的问题在于JPA需要的“鉴别器”列。您正在使用
@heritance
注释,默认情况下,该注释将使用
heritancetype.SINGLE_表
策略。这意味着:

  • 您继承的实体
    Person
    Company
    将放在一个表中
  • JPA将需要一个鉴别器来区分实体类型
  • 为了使其适用于您的用例,我做了以下工作:

    实体:

    DB模式:

    一些测试数据:

    存储库:

    @NoRepositoryBean
    公共接口UserBaseRepository扩展了Crudepository{
    T findByEmail(字符串电子邮件);
    }
    @交易的
    公共接口PersonRepository扩展了UserBaseRepository{
    }
    @交易的
    公共接口CompanyRepository扩展了UserBaseRepository{
    }
    
    JUnit测试:

    公共类MultiRepositoryTest扩展了BaseWebAppContextTest{
    @自动连线
    个人知识库;
    @自动连线
    私人公司储蓄公司储蓄;
    @试验
    public void testGetPersons(){
    列表目标=新的ArrayList();
    personRepository.findAll().forEach(target::add);
    Assert.assertEquals(2,target.size());
    }
    @试验
    上市公司(){
    列表目标=新的ArrayList();
    companyRepository.findAll().forEach(target::add);
    Assert.assertEquals(2,target.size());
    }
    }
    
    上述测试通过。这表明JPA现在正确地利用鉴别器来检索所需的记录


    有关JPA相关理论的问题,请参见此。

    我从教程中克隆了该项目,一切正常。Hibernate生成的SQL看起来如何?你用的是哪种Spring版本?@Achraf如果这对你有用,你能接受这个答案吗?
    @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;
        }
    }
    
    -- 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
    );
    
    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');
    
    @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> {
    
    }
    
    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());
        }
    
    }