2012-02-10 9 views
3

Я работаю над моделью домена, используя Hibernate для нового проекта. У меня есть компания, которая в основном состоит из longName:String, shortName:String и otherNames:Collection<String>.Hibernate: findByExample Criteria using Associations

Я смог установить это хорошо, но теперь я хочу работать над некоторыми функциями DAO, которые позволят пользователю найти Entity по примеру, то есть я должен иметь возможность создать объект Entity и установить некоторые из поля, затем, когда я передаю это в поиск, он должен вернуть список результатов, которые соответствуют установленным полям. Я знаю, что могу это сделать, используя Hibernate Example s.

public List<Entity> findByExample(EntityexampleObject) { 
    try { 
     Criteria criteria = getSession().createCriteria(type); 
     Example example = Example.create(exampleObject).ignoreCase(); 
     criteria.add(example); 

     @SuppressWarnings("unchecked") 
     List<Entity> list = criteria.list(); 
     return list; 
    } catch (HibernateException he) { 
     return null; 
    } 
} 

Но, согласно моему опыту и документации, ассоциации игнорируются при этом. Поэтому моя коллекция строк для otherNames игнорируется, потому что она представлена ​​в базе данных как ассоциация (один-ко-многим).

В идеале, я хотел бы иметь возможность создать объект Entity и добавить к нему otherName, тогда я смогу найти любые объекты, где одна из их коллекции otherName s соответствует аргументу.

Я попытался сделать:

SortedSet<String> names = exampleObject.getNames(); 
if (names != null && !names.isEmpty()) { 
    Criteria newCriteria = criteria.createCriteria("mappedNames"); 
    newCriteria.add(Restrictions.in("string", exampleObject.getNames())); 
} 

Где Строковые литералы здесь представляют имена столбцов, используемых в БД. Это работает в том, что он соединяет таблицы и возвращает результаты, когда один из otherName s в базе данных соответствует критериям. Но я получаю дубликаты, потому что, если у Entity есть два других имени, и критерии поиска ищут их обоих, тогда они отображаются как два результата, потому что объединение создает две строки, представляющие один и тот же Entity, но с каждым из двух других имен. например .:

Entity: 
    longName:foo 
    shortName:bar 
    otherNames: 
     a 
     b 

приведет в два ряде для джойна:

foo, bar, a 
foo, bar, b 

Так что, когда я criteria.list возвращает два Entity объектов, оба из которых являются таким же объектом.

Кто-нибудь знает лучший способ сделать поиск по примеру, используя Hibernate, где поиск фактически рассматривает ассоциацию (которая в этом случае является простой ассоциацией с коллекцией строк)?

ответ

1

Я думаю, что нашел ответ сам, по крайней мере, до такой степени, что он работает для меня. Я по-прежнему заинтересован в другом входе, но сейчас это то, что я сделал:

criteria.setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE); 

это говорит о том, что для возвращения отдельных лиц и в случае любой таблицы соединения, только возвращаем корневой объект.

Смежные вопросы