我的项目在Hibernate中使用JPA 2,并且有一个表单继承设置用于处理两种类型的客户。当我尝试使用Spring Data JPA Specification来查询客户数据时,我总是得到不正确的结果。我认为这是因为我创建了错误的查询,仍然不知道如何使它正确。JPA 2关于单表继承(Hibernate)的条件查询
这里是我的测试代码(我试图通过公司名称搜索客户):
@Test
public void test() {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Customer> customerQuery = criteriaBuilder.createQuery(Customer.class);
Root<Customer> customerRoot = customerQuery.from(Customer.class);
Root<CompanyCustomer> companyCustomerRoot = customerQuery.from(CompanyCustomer.class);
CriteriaQuery<Customer> select = customerQuery.select(customerRoot);
select.where(criteriaBuilder.equal(companyCustomerRoot.get(CompanyCustomer_.companyName), "My Company Name"));
TypedQuery<Customer> query = entityManager.createQuery(select);
List<Customer> results = query.getResultList();
assertEquals(1, results.size()); // always got size 2
}
SQL脚本日志中:
Hibernate:
select
customer0_.id as id2_16_,
customer0_.type as type1_16_,
customer0_.first_name as first_na8_16_,
customer0_.last_name as last_nam9_16_,
customer0_.company_name as company13_16_
from
customers customer0_ cross
join
customers companycus1_
where
companycus1_.type='COMPANY'
and companycus1_.company_name=?
有两条记录在我的数据库:
insert into customers (id, type, company_name) values (1, 'COMPANY', 'My Company Name');
insert into customers (id, type, first_name, last_name) values (2, 'PERSONAL', 'My First Name', 'My Last Name');
我的单表继承设置:
@Entity
@Table(name = "customers")
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
public abstract class Customer {
@Enumerated(EnumType.STRING)
@Column(name = "type", insertable = false, updatable = false)
private CustomerType type;
private String contactNumber;
}
@Entity
@DiscriminatorValue("PERSONAL")
public class PersonalCustomer extends Customer {
private String firstName;
private String lastName;
}
@Entity
@DiscriminatorValue("COMPANY")
public class CompanyCustomer extends Customer {
private String companyName;
}
public enum CustomerType {
COMPANY, PERSONAL;
}
它会返回2行,你可以看到在hibernate中产生了SQL的交叉连接。请你可以解释一下你想从数据库中获取什么 –
@SangramJadhav我试图通过公司名称搜索客户。其实我正在研究搜索功能,测试代码就是其中的一个用例。用户也可以通过名字或姓氏进行搜索。 – user1831877
您需要两种不同的方法来搜索公司和个人。这样,您只能通过公司名称或客户名称进行查询。您的服务层可以根据CustomerType决定调用哪种方法 –