Я использую Jpa 2.2 с финальной флягой Hibernate 5.3.7. Ниже мои лица
и код для теста не выполняется правильно:
Сущность инструктора:
@Entity
@DynamicUpdate
@DynamicInsert
public class Instructor {
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
@GenericGenerator(name = "native", strategy = "native")
private int id;
@Version
@Column(columnDefinition = "int(11) not null default 0")
private int version = 0;
**@OneToOne(mappedBy = "instructor", fetch = FetchType.LAZY, orphanRemoval = true, cascade = CascadeType.ALL)
@JoinColumn(name = "proof_id")
private IdProof idProof;
@OneToMany(mappedBy = "instructor", orphanRemoval = true, cascade = CascadeType.ALL)
private Set<Vehicle> vehicles = new HashSet<>();**
IdProof Entity:
@Entity
@Table(name = "id_proof_tbl")
@DynamicInsert
@DynamicUpdate
public class IdProof {
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
@GenericGenerator(name = "native", strategy = "native")
@Column(updatable = false)
private int id;
@Version
@Column(columnDefinition = "int(11) not null default 0")
private int version;
**@OneToOne(fetch = FetchType.LAZY)
private Instructor instructor;**
Транспортное средство:
@Entity
@DynamicInsert
@DynamicUpdate
public class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
@GenericGenerator(name = "native", strategy = "native")
private int id;
**@ManyToOne(fetch = FetchType.LAZY)
private Instructor instructor;**
**@OneToMany(mappedBy = "vehicle", fetch = FetchType.LAZY, orphanRemoval = true, cascade = CascadeType.ALL)
private Set<Document> documents = new HashSet<>();**
И Документы Entity:
@Entity
@DynamicInsert
@DynamicUpdate
public class Document {
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
@GenericGenerator(name = "native", strategy = "native")
private int id;
**@ManyToOne(fetch = FetchType.LAZY)
private Vehicle vehicle;**
Я получаю данные из базы данных MySQL с кодом, описанным ниже как
Тест JUnit:
@Test
@Rollback(false)
@Transactional
public void fetchPartialDataWithJPQLQueryWithEqualEntityGraph() {
**// Preparing Entity Graph to be passed as a hint .**
EntityGraph<Instructor> instructorGraph =
em.createEntityGraph(Instructor.class);
instructorGraph.addAttributeNodes(Instructor_.idProof);
Subgraph<Vehicle> vehcileSubgraph =
instructorGraph.addSubgraph(Instructor_.VEHICLES);
vehcileSubgraph.addAttributeNodes(Vehicle_.documents);
**//Case 1:**
TypedQuery<Instructor> typedQueryJoinFetch =
em.createQuery(" select i from Instructor i "
+ " join fetch i.idProof id "
+ " join fetch i.vehicles v "
+ " join fetch v.documents vd ",
Instructor.class);
typedQueryJoinFetch.setHint("javax.persistence.fetchgraph",
instructorGraph);
List<Instructor> instructors
=typedQueryJoinFetch.getResultList();
**//Case 2:**
TypedQuery<Instructor> typedQueryLeftJoin =
em.createQuery(" select i from Instructor i "
+ " left join i.idProof id "
+ " left join i.vehicles v "
+ " left join v.documents vd ",
Instructor.class);
typedQueryLeftJoin.setHint("javax.persistence.fetchgraph",
instructorGraph);
List<Instructor> instructorsWithLeftJoin =
typedQueryLeftJoin.getResultList();
**// Case 3:**
try {
TypedQuery<Instructor>
typedQueryLeftJoinAndJoinFetchMixed =
em.createQuery(" select i from Instructor i "
+ " join fetch i.idProof id "
+ " left join i.vehicles v "
+ " join fetch v.documents vd ",
Instructor.class);
typedQueryLeftJoinAndJoinFetchMixed.
setHint("javax.persistence.fetchgraph", instructorGraph);
List<Instructor>
instructorsWithLeftJoinAndJoinFetchMixed =
typedQueryLeftJoinAndJoinFetchMixed
.getResultList();
} catch (Exception e) {
e.printStackTrace();
}
}
**Case 1 executes correctly and results in the inner join between the four
tables with below query:**
select
instructor0_.id as id1_2_0_,
idproof1_.id as id1_1_1_,
vehicles2_.id as id1_5_2_,
documents3_.id as id1_0_3_,
instructor0_.address as address2_2_0_,
instructor0_.birth_date_time as birth_da3_2_0_,
instructor0_.birth_date_time_zone_offset as birth_da4_2_0_,
instructor0_.created_date as created_5_2_0_,
instructor0_.day_off_time as day_off_6_2_0_,
instructor0_.day_start_time as day_star7_2_0_,
instructor0_.father_name as father_n8_2_0_,
instructor0_.mother_name as mother_n9_2_0_,
instructor0_.name as name10_2_0_,
instructor0_.photo as photo11_2_0_,
instructor0_.monthly_salary as monthly12_2_0_,
instructor0_.updated_date as updated13_2_0_,
instructor0_.version as version14_2_0_,
idproof1_.address as address2_1_1_,
idproof1_.created_date as created_3_1_1_,
idproof1_.father_name as father_n4_1_1_,
idproof1_.instructor_id as instruc12_1_1_,
idproof1_.is_foreigner as is_forei5_1_1_,
idproof1_.mother_name as mother_n6_1_1_,
idproof1_.name as name7_1_1_,
idproof1_.proof_sequence_no as proof_se8_1_1_,
idproof1_.sex as sex9_1_1_,
idproof1_.updated_date as updated10_1_1_,
idproof1_.version as version11_1_1_,
vehicles2_.creation_date as creation2_5_2_,
vehicles2_.instructor_id as instruct8_5_2_,
vehicles2_.purchased_date_time as purchase3_5_2_,
vehicles2_.purchased_date_zone_offset as purchase4_5_2_,
vehicles2_.student_id as student_9_5_2_,
vehicles2_.updated_date as updated_5_5_2_,
vehicles2_.vechicle_type as vechicle6_5_2_,
vehicles2_.vehicle_number as vehicle_7_5_2_,
vehicles2_.instructor_id as instruct8_5_0__,
vehicles2_.id as id1_5_0__,
documents3_.name as name2_0_3_,
documents3_.vehicle_id as vehicle_3_0_3_,
documents3_.vehicle_id as vehicle_3_0_1__,
documents3_.id as id1_0_1__
from
instructor instructor0_
inner join
id_proof_tbl idproof1_
on instructor0_.id=idproof1_.instructor_id
inner join
vehicle vehicles2_
on instructor0_.id=vehicles2_.instructor_id
inner join
document documents3_
on vehicles2_.id=documents3_.vehicle_id
**Case 2 executes successfully and results in left outer join between
four tables with below query:**
select
instructor0_.id as id1_2_0_,
idproof1_.id as id1_1_1_,
vehicles2_.id as id1_5_2_,
documents3_.id as id1_0_3_,
instructor0_.address as address2_2_0_,
instructor0_.birth_date_time as birth_da3_2_0_,
instructor0_.birth_date_time_zone_offset as birth_da4_2_0_,
instructor0_.created_date as created_5_2_0_,
instructor0_.day_off_time as day_off_6_2_0_,
instructor0_.day_start_time as day_star7_2_0_,
instructor0_.father_name as father_n8_2_0_,
instructor0_.mother_name as mother_n9_2_0_,
instructor0_.name as name10_2_0_,
instructor0_.photo as photo11_2_0_,
instructor0_.monthly_salary as monthly12_2_0_,
instructor0_.updated_date as updated13_2_0_,
instructor0_.version as version14_2_0_,
idproof1_.address as address2_1_1_,
idproof1_.created_date as created_3_1_1_,
idproof1_.father_name as father_n4_1_1_,
idproof1_.instructor_id as instruc12_1_1_,
idproof1_.is_foreigner as is_forei5_1_1_,
idproof1_.mother_name as mother_n6_1_1_,
idproof1_.name as name7_1_1_,
idproof1_.proof_sequence_no as proof_se8_1_1_,
idproof1_.sex as sex9_1_1_,
idproof1_.updated_date as updated10_1_1_,
idproof1_.version as version11_1_1_,
vehicles2_.creation_date as creation2_5_2_,
vehicles2_.instructor_id as instruct8_5_2_,
vehicles2_.purchased_date_time as purchase3_5_2_,
vehicles2_.purchased_date_zone_offset as purchase4_5_2_,
vehicles2_.student_id as student_9_5_2_,
vehicles2_.updated_date as updated_5_5_2_,
vehicles2_.vechicle_type as vechicle6_5_2_,
vehicles2_.vehicle_number as vehicle_7_5_2_,
vehicles2_.instructor_id as instruct8_5_0__,
vehicles2_.id as id1_5_0__,
documents3_.name as name2_0_3_,
documents3_.vehicle_id as vehicle_3_0_3_,
documents3_.vehicle_id as vehicle_3_0_1__,
documents3_.id as id1_0_1__
from
instructor instructor0_
left outer join
id_proof_tbl idproof1_
on instructor0_.id=idproof1_.instructor_id
left outer join
vehicle vehicles2_
on instructor0_.id=vehicles2_.instructor_id
left outer join
document documents3_
on vehicles2_.id=documents3_.vehicle_id
Но я хочу получить только тех инструкторов, у которых в базе данных присутствуют IdProofs, и только у их транспортных средств есть документы, присутствующие в базе данных. Поэтому я кодировал случай 3. Но случай 3 приводит к следующему исключению:
java.lang.IllegalArgumentException: org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=vd,role=com.katariasoft.technologies.jpaHibernate.college.data.entity.Vehicle.documents,tableName=document,tableAlias=documents3_,origin=vehicle vehicles2_,columns={vehicles2_.id ,className=com.katariasoft.technologies.jpaHibernate.college.data.entity.utils.Document}}] [ select i from com.katariasoft.technologies.jpaHibernate.college.data.entity.Instructor i join fetch i.idProof id left join i.vehicles v join fetch v.documents vd ]
Пожалуйста, дайте мне знать, как я могу выполнить свое требование случая 3 для получения
Все инструкторы, имеющие IdProofs, присутствуют в БД вместе со своими единственными транспортными средствами, имеющими документы в БД.