У меня есть приложение, которое загружает данные, относящиеся к канализационной сети. Вот образец вовлеченных лиц. Сначала я определяю сущность Network:
@Entity
@Table(name = "network")
public class Network extends Serializable {
@Id
@generatedValue(strategy=GenerationType.AUTO)
private Long id;
...
@OneToMany(mappedBy = "network")
private List<Conduit> conduits;
@OneToMany(mappedBy = "network")
private List<ConduitVolumeter> conduitVolumeters;
...
}
Второй задействованный объект - это Conduit, представляющий канал в сети.
@Entity
@Table(name = "conduit")
@NamedQuery(name = "Conduit.findAll", query = "SELECT c FROM Conduit c")
public class Conduit extends Serializable {
@Id
@generatedValue(strategy=GenerationType.AUTO)
private Long id;
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id_network", nullable = false)
private Network network;
@OneToOne(mappedBy = "conduit", fetch = FetchType.LAZY)
private ConduitVolumeter conduitVolumeter;
...
}
Далее я определяю ConduitVolumeter. Он представляет собой измерительное устройство, используемое для измерения объема в трубопроводе. Поскольку объемы могут быть измерены в других сетевых элементах, существует абстрактный класс Volumeter, связанный с таблицей volumeter в базе данных.
@Entity(name = "ConduitVolumeter")
@DiscriminatorValue("1")
public class ConduitVolumeter extends Volumeter {
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id_nme")
private Conduit conduit;
...
}
@Entity
@Table(name = "volumeter")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "nme_type", discriminatorType = DiscriminatorType.INTEGER)
public abstract class Volumeter extends Serializable {
@Id
@generatedValue(strategy=GenerationType.AUTO)
private Long id;
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id_network", nullable = false)
private Network network;
...
}
Проблема в том, что когда я пытаюсь загрузить все каналы, связанные с сетью, Hibernate пытается систематически загружать каждый томомер, связанный с каждым загруженным каналом, по одному, в соответствии с его журналами.
Hibernate:
select
conduit0_.id as id_1_7_,
conduit0_.name as name23_7_,
conduit0_.id_network as id_netw39_7_,
from
conduit conduit0_ cross
join
network network1_
where
conduit0_.id_network=?
...
Hibernate:
select
conduitvol0_.id as id2_116_0_,
conduitvol0_.name as name10_116_0_,
conduitvol0_.id_network as id_netw15_116_0_,
conduitvol0_.id_nme as id_nme17_116_0_
from
volumeter conduitvol0_
where
conduitvol0_.id_nme=?
and conduitvol0_.nme_type=1
Мой вопрос: почему Hibernate пытается загрузить данные томомера? Каждая аннотация @ManyToOne и @OneToOne устанавливается с помощью FetchType.LAZY. Что я упустил?
Кстати, меня просят использовать JPA с устаревшей базой данных. Проблема в модели базы данных? Есть ли способ загрузить кабелепроводы без измерителей объема?
С Уважением.
Франсуа




FetchType - это всего лишь подсказка. Это зависит от того, как вы запрашиваете данные, если вы используете методы репозитория spring-data-jpa, такие как методы findOne или findBy (производные запросы), тогда Lazy должен работать, но если вы используете репозиторий JPA с @Query в методе репозитория и напишите ваш запрос, то Lazy может не работать.
Спасибо за этот ответ. Я попробую. По сути, я использую запрос в репозитории каналов. Я попробую использовать один из методов findBy, чтобы проверить ваш ответ.
Я попытался использовать метод репозитория spring-jpa-data findByNetwork из репозитория каналов. Ничего не меняется. Он загружает объемные метры, как раньше.
Всегда помните, что отложенная загрузка - это намек, а не гарантия.