2013-08-09 6 views
0

Я занят программированием приложения с использованием спящего режима 4.2.2.Final и Spring 3.2.3.RELEASE. Я использую logging framework log4jdbc-remix (0.2.7) для регистрации всех вызовов sql в базе данных. Я использую критерии спящего режима для создания операторов SQL. В одном случае я генерирую инструкцию SQL, которая возвращает результаты, когда я выполняю ее в самой базе данных (DB/2), просто скопируйте-вставьте из вывода журнала. В спящем режиме результирующий список пуст (тот же запрос).Hibernate4 не извлекает данные из базы данных

методы (я меняла имена переменных более «общих английских» имен):

@Override 
public List<PersonId> getActiveNumbers(SpecialNumber specialumber) { 
    final Criteria criteria = this.getCurrentSession().createCriteria(Person.class); 
    criteria.add(Restrictions.eq("specialNr", specialNumber)); 
    criteria.setProjection(Projections.projectionList() 
     .add(Projections.property("id.baseNr")) 
     .add(Projections.property("id.subNr"))); 
    criteria.add(Subqueries.propertiesIn(new String[] { "id.baseNr", "id.subNr" }, 
     isActive())); 
    criteria.setResultTransformer(Transformers.aliasToBean(PersonId.class)); 

    return (List<PersonId>) criteria.list(); 
} 

private DetachedCriteria isActive() { 
    DetachedCriteria isActive = DetachedCriteria.forClass(PersonSpecific.class); 
    isActive.add(LocalDateComposite.lessThanOrEqual("date", LocalDate.now())); 
    isActive.add(Restrictions.or(Restrictions.eq("dateCancel", null), 
     Restrictions.ge("dateCancel", LocalDate.now()))); 
    isActive.setProjection(Projections.projectionList() 
     .add(Projections.property("id.baseNr").as("baseNr")) 
     .add(Projections.property("id.subNr").as("subNr"))); 
    return isActive; 
} 

Однако, когда я удалить строку

criteria.add(Restrictions.eq("specialNr", specialNumber)); 

спящий режим делает генерировать результирующее список. Подзапрос «isActive» возвращает правильный запрос с правильными значениями (в соответствии с журналом, а также при удалении указанной строки).

«specialNr» имеет тип «specialNumber», для которого у меня есть собственный UserType:

public class SpecialNumberUserType extends AbstractUserType implements UserType { 
private static final int[] TYPES = { Types.BIGINT }; 

    [...] 

@Override 
public int[] sqlTypes() { 
    return TYPES; 
} 

@Override 
public Class<?> returnedClass() { 
    return SpecialNumber.class; 
} 

@Override 
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) 
    throws HibernateException, SQLException { 
    if (rs.wasNull()) { 
     return null; 
    } 
    return new specialNumber(rs.getLong(names[0])); 
} 

@Override 
public void nullSafeSet(PreparedStatement st, Object value, int index, 
    SessionImplementor session) throws HibernateException, SQLException { 

    if (null == value) { 
     st.setLong(index, 0L); 
    } else { 
     st.setLong(index, ((SpecialNumber) value).getValue()); 
    } 

} 
} 

Я не могу понять, почему спящий режим делает генерировать правильный SQL, но deosn't получать право результат. Я использую «specialNumber» в других таблицах и запросах, и он работает в других запросах. Только в этом конкретном случае спящий режим не получает результат. Есть идеи? Кажется, что что-то не так с пользовательским типом SpecialNumberUserType, но я не могу понять, что, поскольку полученный sql показывает правильное значение и работает в других sql-операторах, используя тот же класс specialNumber.

- EDIT:

Я забыл упомянуть: когда я запускаю тот же метод против в памяти тестовой БД (HSQLDB), чем я получить ожидаемый результат. Итак, подведем итог:

  1. Сгенерированный sql в порядке, с правильными значениями (проверка журналов);
  2. Выполнение сгенерированного sql непосредственно в базе данных (терминал db/2), я получаю ожидаемый результат;
  3. Выполнение метода getActiveNumbers в базе данных в памяти, я получаю ожидаемый результат;
  4. Запуск метода getActiveNumbers против реальной базы данных, я получаю пустой список, который не является ожидаемым результатом.
  5. Выполнение того же метода, но с линией 'criteria.add (Restrictions.eq ("specialNr", specialNumber)); удалено, я получаю ожидаемый результат этого запроса (что довольно много строк);
  6. Выполнение других запросов (с использованием критериев спящего режима) с использованием того же класса «SpecialNumber», что и свойство другого класса против реальной базы данных, работает - здесь нет кода, но он очень похож, имея строку типа «criteria.add» (Restrictions.eq ("specialNr", specialNumber)); '.

Я озадачен ...

- EDIT_II:

Я пытаюсь заставить его работать с HQL-запросов. То же, очень странно, проблема, и я фокусирование только на «» specialNumber:

final Query query = this.getCurrentSession().createQuery(
     "select * from Person where specialNumber = 436260171"); 

дает ожидаемый результат.(В этом случае 2 записи). Когда я изменить его на:

final Query query = this.getCurrentSession().createQuery(
     "select * from Person where specialNumber = :specialNumber"); 
query.setLong("specialNumber", 436260171L); 

или

query.setParameter("specialNumber", new SpecialNumber(436260171L)); 

я получаю пустой список снова. Итак, используя параметр и внезапно, он больше не работает. Я не понимаю: p.

+0

Я также озадачен. Не знаю, что происходит, но у меня есть выстрел в темноте. Проверьте права доступа к базе данных. Поэтому, когда вы запрашиваете базу данных напрямую, убедитесь, что вы используете одни и те же учетные данные (просто говоря это, потому что большинство из нас использует супер-учетную запись для прямого подключения к db ...). Кроме этого, понятия не имею. – Rafa

+0

Thx для вашего ответа, но да, учетные данные в порядке. Я сделал еще несколько тестов: см. EDIT_II – qsys

ответ

0

И, наконец, решил. Очевидно, что на db-стороне (legacy) тип данных был CHAR. В тестовой базе данных в памяти тип был сопоставлен с целым числом. Вот почему он работал «in-memory», но не на реальном db. Мне нужно было изменить метод nullSafeSet для типа usertype, чтобы он работал правильно ...

EDIT: Было еще хуже: «SpecialNumber» был в разных таблицах, определенных как разные типы: на одном столе это было char (N), в другом, это был большой смысл. У меня все работает сейчас (я думаю).