2011-07-04 15 views
8

Ben NamedQuery sonrasında işe almaya çalışıyorum:Hazırda bekletme: OFFSET ve LIMIT için adlandırılmış bir parametre kullanamazsınız?

@NamedQuery(name="MyEntity.findByUser", query="SELECT m FROM MyEntity m WHERE m.owner = :user OFFSET :offset LIMIT :limit") 

sorun bu hazırda sunucu başlangıçta aşağıdaki yığın-iz patlamaya neden olmasıdır:

[INFO] [talledLocalContainer] java.lang.NullPointerException 
[INFO] [talledLocalContainer] at org.hibernate.hql.ast.ParameterTranslationsImpl.getNamedParameterExpectedType(ParameterTranslationsImpl.java:63) 
[INFO] [talledLocalContainer] at org.hibernate.engine.query.HQLQueryPlan.buildParameterMetadata(HQLQueryPlan.java:296) 
[INFO] [talledLocalContainer] at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:97) 
[INFO] [talledLocalContainer] at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56) 
[INFO] [talledLocalContainer] at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72) 
[INFO] [talledLocalContainer] at org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:400) 
[INFO] [talledLocalContainer] at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:351) 
[INFO] [talledLocalContainer] at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1291) 
[INFO] [talledLocalContainer] at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:713) 
[INFO] [talledLocalContainer] at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:121) 
[INFO] [talledLocalContainer] at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83) 
[INFO] [talledLocalContainer] at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:60) 
(...) 

bazı denemenin ardından -ve-error Ben ": offset" ve ": limit" değişmez değerleri (sırasıyla 0 ve 10) ile değiştirildiğini buldum. Bunun için bir neden var mı? Sorgumda çalışmak için adlandırılmış parametreleri almanın bir yolu var mı?

Tanımlı bir sorgudaki ofset ve sınır değerlerini dinamik olarak ayarlamak için konumlandırılmış parametreler kullanan bazı örnekler gördüm, ancak kodumun okunamayan bir grup query.setParameter(1, "someValue"); saçmalık içine dejenere olmasını istemiyorum. Adlandırılmış parametrelerin bu tür bir çöp kodundan kurtulmaları gerekiyordu.

cevap

17

Hibernate, bu kavramları çalışma zamanında belirlemek için özel bir API'ye sahiptir. Bu deneyin:

@NamedQuery(name="MyEntity.findByUser", 
    query="SELECT m FROM MyEntity m WHERE m.owner = :user") // don't put OFFSET or LIMIT here 

... 

entityManager.createNamedQuery("MyEntity.findByUser") 
.setFirstResult(20) // equivalent to OFFSET 
.setMaxResults(5) // equivalent to LIMIT 
.getResultList(); 

Bu yola bitti nedenini tahmin veritabanı sunucuları diğerinden üstün biçimini almaya makul değil yani, bu kavramlar belirtilir nasıl ve nerede SQL sorgusunda olarak büyük ölçüde değişir ve olmasıdır aralarında dönüştürmek için çok zor.

Böylelikle, diyalekt uygulaması ne yapılması gerektiğini açıkça bilir ve sonra yapabilir.

+3

Teşekkürler, bu yöntem çalışır. Bununla birlikte, neden bariz olmanın nedenini tamamen kabul ettiğimden emin değilim. "OFFSET" ve "LIMIT" anahtar kelimeleri EJBQL spec'in bir parçasıdır. Ve eğer bunlar spesifikasyondaysa, bu şekilde desteklenmelidirler. Üstelik, eğer onların desteğinin düşürülmesi istenirse, sorgudaki değişmez değerler kullanıldığında bile tamamen düşürülmüş olmalıydı. Fikri değerlerin çalıştığı ve parametrelendirilmiş değerlerin mevcut olduğu durumların mevcut durumu, bence, bir hatadır. – aroth

+0

adil yorum - – Bohemian

+0

@aroth adresinden kaldırıldı "bariz": Bu da bana da oldu, ama bu sefer bir dizge param değeri. Parametreyi sabit değere göre değiştirirsem iyi çalışır. Sanırım bu gerçeğin arkasında başka bir hata var. –

İlgili konular