处理实体继承Spring Boot [英] Handling entities inheritance spring boot
问题描述
I'm working with this tutorial to handle entities inheritance. I have person and company entities that extends the User entity.
@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
}
然后扩展UserBaseRepository的UserRpository,PersonRepository和Company Repository.
then UserRpository ,PersonRepository and Company Repository that extends the 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> { }
问题在于调用personRepository.findAll()来获取所有人时,结果我也得到了公司.
the probleme is when calling personRepository.findAll() to get all persons , in result i got also companies.
推荐答案
您的问题出在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:
- 您继承的实体
Person
和Company
将进入一个表. - JPA将需要一个鉴别器来区分实体类型.
- Your inherited entities
Person
andCompany
will go into a single table. - 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.
这篇关于处理实体继承Spring Boot的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!