Размер сбора счетчика Hibernate без инициализации

Есть ли способ подсчитать размер связанной коллекции без инициализации?

например

Select count(p.children) from Parent p 

(есть веская причина, почему я не могу сделать это каким-либо другим способом, так как предложение where where более сложное, а my from – полиморфный запрос)

Благодарю.

Возможным решением, отличным от запросов, может быть отображение children lazy="extra" с lazy="extra" (в XML-нотации). Таким образом, вы можете получить родителя с любым запросом, который вам нужен, а затем вызвать parent.getChildren().size() без загрузки всей коллекции (выполняется только запрос типа SELECT COUNT ).

С аннотациями это было бы

 @OneToMany @org.hibernate.annotations.LazyCollection( org.hibernate.annotations.LazyCollectionOption.EXTRA ) private Set children = new HashSet(); 

Обновление: Цитата из Java Persistence with Hibernate , ch. 13.1.3:

Прокси инициализируется, если вы вызываете какой-либо метод, который не является методом getter идентификатора, сбор инициализируется, если вы начинаете выполнять итерацию через свои элементы или вы вызываете какие-либо операции управления коллекцией, такие как size() и contains() . Hibernate предоставляет дополнительную настройку, которая в основном полезна для больших коллекций; они могут отображаться как лишние . […]

[Mapped, как указано выше], коллекция больше не инициализируется, если вы вызываете size() , contains() или isEmpty() – запрашивается firebase database для получения необходимой информации. Если это Map или List , операции containsKey() и get() также напрямую запрашивают базу данных.

Таким образом, с объектом, указанным выше, вы можете сделать

 Parent p = // execute query to load desired parent // due to lazy loading, at this point p.children is a proxy object int count = p.getChildren().size(); // the collection is not loaded, only its size 

Вы можете использовать Session # createFilter, который является формой HQL, которая явно работает с коллекциями. Например, вы упомянули родителя и детей, поэтому, если у вас есть Person p, самая простая форма:

 session.createFilter( p.getChildren(), "" ).list() 

Это просто возвращает вам список детей. Важно отметить, что возвращенная коллекция не «живая», она никоим образом не связана с p.

Интересная часть исходит из второго аргумента. Это fragment HQL. Здесь, например, вы можете:

 session.createFilter( p.getChildren(), "select count(*)" ).uniqueResult(); 

Вы упомянули, что у вас есть предложение where, поэтому вы также можете захотеть:

 session.createFilter( p.getChildren(), "select count(*) where this.age > 18" ).uniqueResult(); 

Обратите внимание, что из предложения нет. То есть, из предложения подразумевается предложение from. Элементам коллекции присваивается псевдоним «this», поэтому вы можете ссылаться на него из других частей fragmentа HQL.

Вы можете сделать то же самое вот так:

 @Override public FaqQuestions getFaqQuestionById(Long questionId) { session = sessionFactory.openSession(); tx = session.beginTransaction(); FaqQuestions faqQuestions = null; try { faqQuestions = (FaqQuestions) session.get(FaqQuestions.class, questionId); Hibernate.initialize(faqQuestions.getFaqAnswers()); tx.commit(); faqQuestions.getFaqAnswers().size(); } finally { session.close(); } return faqQuestions; } 

Просто используйте faqQuestions.getFaqAnswers (). Size () в вашем controllerе, и вы получите размер, если лениво проинсталлирован список, не получая сам список.

Давайте будем гением компьютера.