#java #spring #hibernate #jpa
#java #весна #спящий режим #jpa
Вопрос:
У меня есть три таблицы: ScanMeta, Scan и Batch.
@Entity
@Table(name = "scan_meta_letter")
public class ScanMetaLetter {
@Id
@Column(name = "scan_meta_id")
private Long id;
@OneToOne(mappedBy = "scanMeta")
@JoinColumn(name = "scan_id")
private Scan scan;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
....
}
@Entity
@Table(name = "scan")
public class Scan {
@Id
@GeneratedValue
@Column(name = "scan_id")
private Long id;
@Column(name = "read_date")
private OffsetDateTime readDate;
@Column(name = "deletion_date")
private OffsetDateTime deletionDate;
@Column(name = "type", length = 10)
@Enumerated(EnumType.STRING)
private ScanType type;
@ManyToOne(fetch = FetchType.LAZY)
private Batch batch;
....
}
@Entity
@Table(name = "batch")
public class Batch {
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@Column(name = "batch_status")
@Enumerated(EnumType.STRING)
private BatchStatus batchStatus;
@Column(name = "batch_type", length = 10)
@Enumerated(EnumType.STRING)
private BatchType batchType;
....
}
Когда я создаю Specification<ScanMettaLetter>
, я извлекаю таблицы: сканирование и пакет.
Specification<ScanMetaLetter> s = Specification.where((root, criteriaQuery, criteriaBuilder) -> {
criteriaQuery.distinct(true);
root.fetch("scan", JoinType.LEFT).fetch("batch", JoinType.LEFT);
return null;
});
Если я хотел бы, чтобы ответ сортировался по scan.type — все в порядке. Но если сортировать по — scan.batch.BatchStatus, я получаю сообщение об ошибке:
could not prepare statement; SQL [select distinct scanmetale0_.scan_meta_id as scan_met1_7_0_,
scan1_.scan_id as scan_id1_3_1_, batch2_.id as id1_0_2_, scanmetale0_.first_name as
recipien3_9_0_, scanmetale0_.last_name as recipien5_9_0_, scan1_.batch_id as
batch_i13_3_1_, scan1_.deletion_date as deletion3_3_1_, scan1_.read_date as read_dat8_3_1_,
scan1_.type as type11_3_1_, batch2_.batch_status as batch_st3_0_2_,
batch2_.batch_type as batch_ty4_0_2_ from
scan_meta_letter scanmetale0_ left outer join scan scan1_ on
scanmetale0_.scan_meta_id=scan1_.scan_id left outer join batch batch2_ on
scan1_.batch_id=batch2_.id cross join batch batch6_ where scan1_.batch_id=batch6_.id and
(scan1_.reg_code like ?) and scan1_.type=? and batch6_.batch_status=? and 1=1 order by
batch6_.batch_status asc limit ?]; nested exception is
org.hibernate.exception.SQLGrammarException: could not prepare statement
Я вижу, что создано два псевдонима для batch -> batch2 и batch6. Почему? Могу ли я как-то обойти это?
Комментарии:
1. «Могу ли я как-то обойти это?» — Я бы так не подумал, потому
FETCH JOIN
что s не может быть псевдоним, поэтому, когда выscan.batch
снова ссылаетесь на запрос, это обязательно будет отдельное соединение. Вместо этого вы можете попробовать использовать обычные соединения и предоставить график загрузки для запроса, хотя это, вероятно, просто приведет к разделениюSELECT
2. Кроме того, зачем извлекать
ScanMetaLetter.scan
? Разве он уже не загружен с нетерпением?