View Javadoc
1   /*******************************************************************************
2    *   Gisgraphy Project 
3    * 
4    *   This library is free software; you can redistribute it and/or
5    *   modify it under the terms of the GNU Lesser General Public
6    *   License as published by the Free Software Foundation; either
7    *   version 2.1 of the License, or (at your option) any later version.
8    * 
9    *   This library is distributed in the hope that it will be useful,
10   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   *   Lesser General Public License for more details.
13   * 
14   *   You should have received a copy of the GNU Lesser General Public
15   *   License along with this library; if not, write to the Free Software
16   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
17   * 
18   *  Copyright 2008  Gisgraphy project 
19   *  David Masclet <davidmasclet@gisgraphy.com>
20   *  
21   *  
22   *******************************************************************************/
23  package com.gisgraphy.domain.repository;
24  
25  import java.util.ArrayList;
26  import java.util.List;
27  
28  import javax.persistence.PersistenceException;
29  
30  import org.hibernate.HibernateException;
31  import org.hibernate.Query;
32  import org.hibernate.Session;
33  import org.springframework.orm.hibernate3.HibernateCallback;
34  import org.springframework.stereotype.Repository;
35  import org.springframework.util.Assert;
36  
37  import com.gisgraphy.domain.geoloc.entity.Adm;
38  import com.gisgraphy.domain.geoloc.entity.GisFeature;
39  
40  /**
41   * A data access object for {@link Adm}
42   * 
43   * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a>
44   */
45  @Repository
46  public class AdmDao extends GenericGisDao<Adm> implements IAdmDao {
47  
48      public AdmDao() {
49  	super(Adm.class);
50      }
51      
52      @Override
53      public Adm get(final Long id) {
54  	Assert.notNull(id, "Can not retrieve an Ogject with a null id");
55  	Adm returnValue = null;
56  	try {
57  	    return (Adm) this.getHibernateTemplate().execute(
58  		    new HibernateCallback() {
59  
60  			public Object doInHibernate(Session session)
61  				throws PersistenceException {
62  			    String queryString = "from "
63  				    + persistentClass.getSimpleName()
64  				    + " o where o.id=" + id;
65  
66  			    Query qry = session.createQuery(queryString);
67  			    qry.setCacheable(true);
68  			    return (Adm) qry.uniqueResult();
69  
70  			}
71  		    });
72  	} catch (Exception e) {
73  	    logger.info("could not retrieve object of type "
74  		    + persistentClass.getSimpleName() + " with id " + id, e);
75  	}
76  	return returnValue;
77      }
78  
79      
80      
81      /**
82       * Check that codes are consistent according the level (see
83       * {@link Adm#isConsistentForLevel() } and save it in the datastore
84       * 
85       * @param adm
86       *                The Adm to save
87       * @return the saved instance
88       * @see Adm#isConsistentForLevel()
89       */
90      @Override
91      public Adm save(Adm adm) {
92  	if (!adm.isConsistentForLevel()) {
93  	    throw new RuntimeException(
94  		    "Level and AdmXCode are inconsistant for " + adm.toString());
95  	}
96  	return super.save(adm);
97      }
98  
99      /*
100      * (non-Javadoc)
101      * 
102      * @see com.gisgraphy.domain.repository.IAdmDao#getAdm1(java.lang.String,
103      *      java.lang.String)
104      */
105     public Adm getAdm1(final String countryCode, final String adm1Code) {
106 	Assert.notNull(countryCode);
107 	Assert.notNull(adm1Code);
108 	return (Adm) this.getHibernateTemplate().execute(
109 		new HibernateCallback() {
110 
111 		    public Object doInHibernate(Session session)
112 			    throws PersistenceException {
113 			String queryString = "from "
114 				+ Adm.class.getSimpleName()
115 				+ " as a where a.countryCode = ? and a.adm1Code= ? and a.level=1";
116 
117 			Query qry = session.createQuery(queryString);
118 			qry.setCacheable(true);
119 
120 			qry.setParameter(0, countryCode.toUpperCase());
121 			qry.setParameter(1, adm1Code);
122 
123 			Adm result = (Adm) qry.uniqueResult();
124 
125 			return result;
126 		    }
127 		});
128     }
129 
130     /*
131      * (non-Javadoc)
132      * 
133      * @see com.gisgraphy.domain.repository.IAdmDao#getAdm2(java.lang.String,
134      *      java.lang.String, java.lang.String)
135      */
136     public Adm getAdm2(final String countryCode, final String adm1Code,
137 	    final String adm2Code) {
138 	Assert.notNull(countryCode);
139 	Assert.notNull(adm1Code);
140 	Assert.notNull(adm2Code);
141 
142 	return (Adm) this.getHibernateTemplate().execute(
143 		new HibernateCallback() {
144 
145 		    public Object doInHibernate(Session session)
146 			    throws PersistenceException {
147 			String queryString = "from "
148 				+ Adm.class.getSimpleName()
149 				+ " as a where a.countryCode=? and a.adm2Code=?";
150 			if (!"00".equals(adm1Code)) {
151 			    queryString += "and a.adm1Code= ?";
152 			}
153 			queryString += " and a.level=2";
154 
155 			Query qry = session.createQuery(queryString);
156 			qry.setCacheable(true);
157 
158 			qry.setParameter(0, countryCode.toUpperCase());
159 			qry.setParameter(1, adm2Code);
160 			if (!"00".equals(adm1Code)) {
161 			    qry.setParameter(2, adm1Code);
162 			}
163 
164 			Adm result;
165 			try {
166 			    result = (Adm) qry.uniqueResult();
167 			} catch (HibernateException e) {
168 			    if (!"00".equals(adm1Code)) {
169 				throw e;
170 			    } else {
171 				logger
172 					.error("Can not retrieve Adm for countrycode="
173 						+ countryCode
174 						+ " and adm2code="
175 						+ adm2Code
176 						+ " in flex mode : result is ambiguous");
177 				return null;
178 			    }
179 			}
180 
181 			return result;
182 		    }
183 		});
184     }
185 
186     /*
187      * (non-Javadoc)
188      * 
189      * @see com.gisgraphy.domain.repository.IAdmDao#getAdm3(java.lang.String,
190      *      java.lang.String, java.lang.String, java.lang.String)
191      */
192     public Adm getAdm3(final String countryCode, final String adm1Code,
193 	    final String adm2Code, final String adm3Code) {
194 	Assert.notNull(countryCode);
195 	Assert.notNull(adm1Code);
196 	Assert.notNull(adm2Code);
197 	Assert.notNull(adm3Code);
198 	return (Adm) this.getHibernateTemplate().execute(
199 		new HibernateCallback() {
200 
201 		    public Object doInHibernate(Session session)
202 			    throws PersistenceException {
203 			String queryString = "from "
204 				+ Adm.class.getSimpleName()
205 				+ " as a where a.countryCode=? and a.adm2Code=? and a.adm3Code=?";
206 			if (!"00".equals(adm1Code)) {
207 			    queryString += "and a.adm1Code= ?";
208 			}
209 			queryString += " and a.level=3";
210 
211 			Query qry = session.createQuery(queryString);
212 			qry.setCacheable(true);
213 
214 			qry.setParameter(0, countryCode.toUpperCase());
215 			qry.setParameter(1, adm2Code);
216 			qry.setParameter(2, adm3Code);
217 
218 			if (!"00".equals(adm1Code)) {
219 			    qry.setParameter(3, adm1Code);
220 			}
221 
222 			Adm result;
223 			try {
224 			    result = (Adm) qry.uniqueResult();
225 			} catch (HibernateException e) {
226 			    if (!"00".equals(adm1Code)) {
227 				throw e;
228 			    } else {
229 				logger
230 					.error("Can not retrieve Adm for countrycode="
231 						+ countryCode
232 						+ " and adm2code="
233 						+ adm2Code
234 						+ " and adm3code="
235 						+ adm3Code
236 						+ " in flex mode : result is ambiguous");
237 				return null;
238 			    }
239 			}
240 
241 			return result;
242 		    }
243 		});
244     }
245 
246     /*
247      * (non-Javadoc)
248      * 
249      * @see com.gisgraphy.domain.repository.IAdmDao#getAdm4(java.lang.String,
250      *      java.lang.String, java.lang.String, java.lang.String,
251      *      java.lang.String)
252      */
253     public Adm getAdm4(final String countryCode, final String adm1Code,
254 	    final String adm2Code, final String adm3Code, final String adm4Code) {
255 	Assert.notNull(countryCode);
256 	Assert.notNull(adm1Code);
257 	Assert.notNull(adm2Code);
258 	Assert.notNull(adm3Code);
259 	Assert.notNull(adm4Code);
260 
261 	return (Adm) this.getHibernateTemplate().execute(
262 		new HibernateCallback() {
263 
264 		    public Object doInHibernate(Session session)
265 			    throws PersistenceException {
266 			String queryString = "from "
267 				+ Adm.class.getSimpleName()
268 				+ " as a where a.countryCode=? and a.adm2Code=? and a.adm3Code=? and a.adm4Code=?";
269 			if (!"00".equals(adm1Code)) {
270 			    queryString += "and a.adm1Code= ?";
271 			}
272 			queryString += " and a.level=4";
273 
274 			Query qry = session.createQuery(queryString);
275 			qry.setCacheable(true);
276 
277 			qry.setParameter(0, countryCode.toUpperCase());
278 			qry.setParameter(1, adm2Code);
279 			qry.setParameter(2, adm3Code);
280 			qry.setParameter(3, adm4Code);
281 
282 			if (!"00".equals(adm1Code)) {
283 			    qry.setParameter(4, adm1Code);
284 			}
285 
286 			Adm result;
287 			try {
288 			    result = (Adm) qry.uniqueResult();
289 			} catch (HibernateException e) {
290 			    if (!"00".equals(adm1Code)) {
291 				throw e;
292 			    } else {
293 				logger
294 					.error("Can not retrieve Adm for countrycode="
295 						+ countryCode
296 						+ " and adm2code="
297 						+ adm2Code
298 						+ " and adm3code="
299 						+ adm3Code
300 						+ " and adm4code="
301 						+ adm4Code
302 						+ " in flex mode : result is ambiguous");
303 				return null;
304 			    }
305 			}
306 
307 			return result;
308 		    }
309 		});
310     }
311 
312     private boolean isAdmCodeEmpty(String admCode) {
313 	if (admCode == null || admCode.trim().equals("")) {
314 	    return true;
315 	}
316 	return false;
317     }
318 
319     /*
320      * (non-Javadoc)
321      * 
322      * @see com.gisgraphy.domain.repository.IAdmDao#getAdm(java.lang.String,
323      *      java.lang.String, java.lang.String, java.lang.String,
324      *      java.lang.String)
325      */
326     public Adm getAdm(final String countryCode, final String adm1Code,
327 	    final String adm2Code, final String adm3Code, final String adm4Code) {
328 	Assert.notNull(countryCode);
329 	if (!isAdmCodeEmpty(countryCode)) {
330 	    if (!isAdmCodeEmpty(adm1Code)) {
331 		if (!isAdmCodeEmpty(adm2Code)) {
332 		    if (!isAdmCodeEmpty(adm3Code)) {
333 			if (!isAdmCodeEmpty(adm4Code)) {
334 			    // adm1,adm2,adm3,adm4
335 			    return getAdm4(countryCode, adm1Code, adm2Code,
336 				    adm3Code, adm4Code);
337 			} else {
338 			    // adm1,adm2,adm3,null
339 			    return getAdm3(countryCode, adm1Code, adm2Code,
340 				    adm3Code);
341 			}
342 		    } else {
343 			// adm1,Adm2, null..
344 			return getAdm2(countryCode, adm1Code, adm2Code);
345 		    }
346 		} else {
347 		    // adm1,null...
348 		    return getAdm1(countryCode, adm1Code);
349 		}
350 	    } else {
351 		logger.info("Can not retrieve an adm if Adm1code is null");
352 		// if adm1 is empty can not retrieve any Adm
353 		return null;
354 	    }
355 	} else {
356 	    return null;
357 	}
358 
359     }
360 
361     /*
362      * (non-Javadoc)
363      * 
364      * @see com.gisgraphy.domain.repository.IAdmDao#getUnused()
365      */
366     @SuppressWarnings("unchecked")
367     public List<Adm> getUnused() {
368 	return (List<Adm>) this.getHibernateTemplate().execute(
369 		new HibernateCallback() {
370 
371 		    public Object doInHibernate(final Session session)
372 			    throws PersistenceException {
373 			final String queryString = "from "
374 				+ Adm.class.getSimpleName()
375 				+ " as a where a not in (select distinct(g.adm) from GisFeature g)";
376 
377 			final Query qry = session.createQuery(queryString);
378 			qry.setCacheable(true);
379 
380 			List<Adm> result = qry.list();
381 			if (result == null) {
382 			    result = new ArrayList<Adm>();
383 			}
384 
385 			return result;
386 		    }
387 		});
388     }
389 
390     /*
391      * (non-Javadoc)
392      * 
393      * @see com.gisgraphy.domain.repository.GenericGisDao#getDirty()
394      */
395     @Override
396     @SuppressWarnings("unchecked")
397     public List<Adm> getDirties() {
398 	return (List<Adm>) this.getHibernateTemplate().execute(
399 		new HibernateCallback() {
400 
401 		    public Object doInHibernate(final Session session)
402 			    throws PersistenceException {
403 			final String queryString = "from "
404 				+ Adm.class.getSimpleName()
405 				+ " as a where a.featureId < 0";
406 
407 			final Query qry = session.createQuery(queryString);
408 			qry.setCacheable(true);
409 
410 			List<Adm> result = qry.list();
411 			if (result == null) {
412 			    result = new ArrayList<Adm>();
413 			}
414 
415 			return result;
416 		    }
417 		});
418     }
419 
420     /*
421      * (non-Javadoc)
422      * 
423      * @see com.gisgraphy.domain.repository.IAdmDao#getAllbyLevel(java.lang.Integer)
424      */
425     @SuppressWarnings("unchecked")
426     public List<Adm> getAllbyLevel(final int level) {
427 	return (List<Adm>) this.getHibernateTemplate().execute(
428 		new HibernateCallback() {
429 
430 		    public Object doInHibernate(final Session session)
431 			    throws PersistenceException {
432 			final String queryString = "from "
433 				+ Adm.class.getSimpleName()
434 				+ " as a where a.level=?";
435 
436 			final Query qry = session.createQuery(queryString);
437 			qry.setCacheable(true);
438 
439 			qry.setParameter(0, level);
440 
441 			List<Adm> result = qry.list();
442 			if (result == null) {
443 			    result = new ArrayList<Adm>();
444 			}
445 
446 			return result;
447 		    }
448 		});
449     }
450 
451     /*
452      * (non-Javadoc)
453      * 
454      * @see com.gisgraphy.domain.repository.IAdmDao#countByLevel(int)
455      */
456     public long countByLevel(final int level) {
457 	// level is of type int =>could not be null
458 	return ((Long) this.getHibernateTemplate().execute(
459 		new HibernateCallback() {
460 
461 		    public Object doInHibernate(Session session)
462 			    throws PersistenceException {
463 			String queryString = "select count(*) from "
464 				+ Adm.class.getSimpleName()
465 				+ " a where a.level=? ";
466 
467 			Query qry = session.createQuery(queryString);
468 			qry.setCacheable(true);
469 			qry.setParameter(0, level);
470 
471 			Long result = (Long) qry.uniqueResult();
472 			return result;
473 		    }
474 		})).longValue();
475     }
476 
477     /*
478      * (non-Javadoc)
479      * 
480      * @see com.gisgraphy.domain.repository.IAdmDao#getAdmByCountryAndCodeAndLevel(java.lang.String,
481      *      java.lang.String, int)
482      */
483     @SuppressWarnings("unchecked")
484     public List<Adm> getAdmByCountryAndCodeAndLevel(final String countryCode,
485 	    final String admCode, final int level) {
486 	Assert.notNull(countryCode);
487 	Assert.notNull(admCode);
488 	// level is a int =>can not be null
489 	return (List<Adm>) this.getHibernateTemplate().execute(
490 		new HibernateCallback() {
491 
492 		    public Object doInHibernate(Session session)
493 			    throws PersistenceException {
494 			String queryString = "from "
495 				+ Adm.class.getSimpleName()
496 				+ " as a where  a.countryCode= ? and a.adm"
497 				+ level + "Code = ?  and a.level=?";
498 
499 			Query qry = session.createQuery(queryString);
500 			qry.setCacheable(true);
501 
502 			qry.setParameter(0, countryCode.toUpperCase());
503 			qry.setParameter(1, admCode);
504 			qry.setParameter(2, level);
505 
506 			List<Adm> result = (List<Adm>) qry.list();
507 			if (result == null) {
508 			    return new ArrayList<Adm>();
509 			}
510 			return result;
511 		    }
512 		});
513     }
514 
515     /*
516      * (non-Javadoc)
517      * 
518      * @see com.gisgraphy.domain.repository.IAdmDao#getAdmOrFirstValidParentIfNotFound(java.lang.String,
519      *      java.lang.String, java.lang.String, java.lang.String,
520      *      java.lang.String)
521      */
522     public Adm getAdmOrFirstValidParentIfNotFound(final String countryCode,
523 	    final String adm1Code, final String adm2Code,
524 	    final String adm3Code, final String adm4Code) {
525 	Assert.notNull(countryCode);
526 	Adm adm = null;
527 	String adm1CodeTemp = adm1Code;
528 	String adm2CodeTemp = adm2Code;
529 	String adm3CodeTemp = adm3Code;
530 	String adm4CodeTemp = adm4Code;
531 	do {
532 	    adm = getAdm(countryCode, adm1CodeTemp, adm2CodeTemp, adm3CodeTemp,
533 		    adm4CodeTemp);
534 	    if (adm == null) {
535 		// downgrade the admvalue to search a lower level
536 		if (adm4CodeTemp != null) {
537 		    adm4CodeTemp = null;
538 		    continue;
539 		} else if (adm3CodeTemp != null) {
540 		    adm3CodeTemp = null;
541 		    continue;
542 		} else if (adm2CodeTemp != null) {
543 		    adm2CodeTemp = null;
544 		    continue;
545 		} else {
546 		    return getAdm1(countryCode, adm1Code);
547 		}
548 	    } else {
549 		return adm;
550 	    }
551 	} while (adm == null);
552 	return adm;
553     }
554 
555     /*
556      * (non-Javadoc)
557      * 
558      * @see com.gisgraphy.domain.repository.IAdmDao#suggestMostAccurateAdm(java.lang.String,
559      *      java.lang.String, java.lang.String, java.lang.String,
560      *      java.lang.String, com.gisgraphy.domain.geoloc.entity.GisFeature)
561      */
562     public Adm suggestMostAccurateAdm(String countryCode, String adm1Code,
563 	    String adm2Code, String adm3Code, String adm4Code,
564 	    GisFeature gisfeature) {
565 	Assert.notNull(countryCode);
566 	logger.debug("try to find ADM for " + adm1Code + "." + adm2Code + "."
567 		+ adm3Code + "." + adm4Code);
568 	Adm adm = getAdm(countryCode.toUpperCase(), adm1Code, adm2Code,
569 		adm3Code, adm4Code);
570 	if (adm == null) {
571 	    // must get the most accurate adm
572 	    String lowestNotNullAdmCode = getLowestNotNullAdmCode(adm1Code,
573 		    adm2Code, adm3Code, adm4Code);
574 	    int level = Adm.getProcessedLevelFromCodes(adm1Code, adm2Code,
575 		    adm3Code, adm4Code);
576 
577 	    if (lowestNotNullAdmCode != null && level != 0) {
578 		List<Adm> levelAdms = getAdmByCountryAndCodeAndLevel(
579 			countryCode.toUpperCase(), lowestNotNullAdmCode, level);
580 		Adm levelAdm = null;
581 		if (levelAdms.size() == 1) {
582 		    levelAdm = levelAdms.get(0);
583 		}
584 		Adm nearestParentAdm = getAdmOrFirstValidParentIfNotFound(
585 			countryCode.toUpperCase(), adm1Code, adm2Code,
586 			adm3Code, adm4Code);
587 		if (levelAdm != null) {
588 		    if (nearestParentAdm != null) {
589 			if (((level - nearestParentAdm.getLevel()) <= 2)) {
590 			    // the admcode of the lowestlevel is probably not
591 			    // well set, return the specified level Adm
592 			    logger.warn("[wrong adm" + (level - 1)
593 				    + "code] : The adm" + (level - 1)
594 				    + "Code for " + gisfeature + "[" + adm1Code
595 				    + "." + adm2Code + "." + adm3Code + "."
596 				    + adm4Code
597 				    + "] is wrong. Please correct it to "
598 				    + levelAdm);
599 			    return levelAdm;
600 			} else {
601 			    logger
602 				    .warn("[wrong adm codes] : "
603 					    + ((level - nearestParentAdm
604 						    .getLevel()) - 1)
605 					    + " admCodes are wrong for "
606 					    + gisfeature
607 					    + "["
608 					    + adm1Code
609 					    + "."
610 					    + adm2Code
611 					    + "."
612 					    + adm3Code
613 					    + "."
614 					    + adm4Code
615 					    + "] but the adm"
616 					    + level
617 					    + "code is corect. The suggested Adm is "
618 					    + nearestParentAdm);
619 			    return nearestParentAdm;
620 			}
621 
622 		    } else {
623 			logger.error("[Wrong adm codes] an Adm" + level
624 				+ " exists but no parent for " + adm1Code + "."
625 				+ adm2Code + "." + adm3Code + "." + adm4Code
626 				+ " : all the code before adm" + level
627 				+ " are wrong");
628 			return levelAdm;
629 		    }
630 		} else {
631 		    // there is no adm with this code for this level, we return
632 		    // the nearest parent
633 		    // split logs
634 		    if ((nearestParentAdm != null)
635 			    && ((level - nearestParentAdm.getLevel()) == 1)) {
636 			logger
637 				.warn("[wrong adm"
638 					+ level
639 					+ "Code] The adm"
640 					+ (level)
641 					+ "Code for "
642 					+ gisfeature
643 					+ "["
644 					+ adm1Code
645 					+ "."
646 					+ adm2Code
647 					+ "."
648 					+ adm3Code
649 					+ "."
650 					+ adm4Code
651 					+ "] is not well set. The nearest parent found is "
652 					+ nearestParentAdm);
653 		    } else {
654 			logger
655 				.warn("[wrong adm codes] The adm"
656 					+ (level)
657 					+ "Code for "
658 					+ gisfeature
659 					+ "["
660 					+ adm1Code
661 					+ "."
662 					+ adm2Code
663 					+ "."
664 					+ adm3Code
665 					+ "."
666 					+ adm4Code
667 					+ "] is not well set and some others. The nearest parent found is "
668 					+ nearestParentAdm);
669 		    }
670 		    return nearestParentAdm;
671 
672 		}
673 	    } else {
674 		// The specified adm code doesn't allow a search
675 		logger.warn("No adm can be found for [" + adm1Code + "."
676 			+ adm2Code + "." + adm3Code + "." + adm4Code + "]");
677 		return null;
678 	    }
679 	} else {
680 	    return adm;
681 	}
682     }
683 
684     public int deleteAllByLevel(final int level) {
685 	return ((Integer) this.getHibernateTemplate().execute(
686 		new HibernateCallback() {
687 
688 		    public Object doInHibernate(Session session)
689 			    throws PersistenceException {
690 			String queryString = "delete from "
691 				+ persistentClass.getSimpleName()
692 				+ " as a where a.level=?";
693 
694 			Query qry = session.createQuery(queryString);
695 			qry.setParameter(0, level);
696 			qry.setCacheable(false);
697 
698 			return Integer.valueOf(qry.executeUpdate());
699 
700 		    }
701 		})).intValue();
702     }
703 
704     private String getLowestNotNullAdmCode(String adm1Code, String adm2Code,
705 	    String adm3Code, String adm4Code) {
706 	if (!isAdmCodeEmpty(adm1Code)) {
707 	    if (!isAdmCodeEmpty(adm2Code)) {
708 		if (!isAdmCodeEmpty(adm3Code)) {
709 		    if (!isAdmCodeEmpty(adm4Code)) {
710 			// adm1,adm2,adm3,adm4
711 			return adm4Code;
712 		    } else {
713 			// adm1,adm2,adm3,null
714 			return adm3Code;
715 		    }
716 		} else {
717 		    // adm1,Adm2, null..
718 		    return adm2Code;
719 		}
720 	    } else {
721 		// adm1,null...
722 		return adm1Code;
723 	    }
724 	} else {
725 	    // if adm1 is empty can not retrieve any Adm
726 	    return null;
727 	}
728     }
729 
730     @SuppressWarnings("unchecked")
731     public List<Long> listFeatureIdByLevel(final int level) {
732 	return ((List<Long>) this.getHibernateTemplate().execute(
733 		new HibernateCallback() {
734 
735 		    public Object doInHibernate(final Session session)
736 			    throws PersistenceException {
737 			final String queryString = "select featureId from "
738 				+ persistentClass.getSimpleName()
739 				+ " as a where a.level=?";
740 
741 			final Query qry = session.createQuery(queryString);
742 			qry.setParameter(0, level);
743 			qry.setCacheable(false);
744 			return qry.list();
745 
746 		    }
747 		}));
748     }
749     
750 
751 }