Почему связанные коллекции содержат нулевые значения? (Спящий, Аннотация, Весна) - PullRequest
3 голосов
/ 26 мая 2009

[Редактировать: По-видимому, это проблема только для массивов, и ответ FoxyBOA может направить (или даже является) ответ.]

Мой вопрос касается следующих программ: Hibernate3 + Annotation, Spring MVC, MySQL и в этом примере также Spring Security.

Мне было интересно, почему коллекции, которые автоматически связываются с Hibernate, содержат нулевые значения для каждого номера строки дочерней таблицы (кроме правильных элементов). Мой пример:

У меня есть пользователи и полномочия , первичный ключ таблицы users - username , который служит внешним ключом , Сейчас в моей таблице полномочия есть 13 строк. Когда я извлекаю пользователя из базы данных (MySQL InnoDB), и Hibernate автоматически извлекает права доступа пользователя, соответствующие этому сопоставлению:

@OneToMany
@JoinColumn(name = "username")
@IndexColumn(name="id") // "id" was the primary key and is used to sort the elements
public Authority[] getAuthorities() {
    return authorities;
}
public void setAuthorities(Authority[] authorities) {
    this.authorities = authorities;
}

... В итоге я получил коллекцию "полномочий", содержащую 14 (0-13) элементов, из которых только четыре не равны нулю (четыре строки в таблице базы данных принадлежат этому конкретному пользователю, так что это правильно). Насколько я понимаю, я использую значения по умолчанию Hibernate для таких свойств, как Fetchmode и т. Д. Я получаю пользователя следующим образом:

Criteria criteria = getSession().createCriteria(User.class);
criteria.add(Restrictions.eq("username",username));
User user = (User) criteria.uniqueResult();

Информация журнала из org.hibernate.loader.loader правильно "упоминает" четыре строки для набора результатов. Тем не менее, созданный пользователь имеет четыре правильных элемента плюс десять нулевых значений в массиве. В моем конкретном примере это приводит к следующему исключению:

java.lang.IllegalArgumentException: Granted authority element 0 is null - GrantedAuthority[] cannot contain any null elements

Ответы [ 2 ]

3 голосов
/ 26 мая 2009

Ответ лежит в аннотации @IndexColumn. Он использует значение id в качестве индекса массива, поэтому количество элементов в массиве в основном будет значением самого высокого идентификатора в таблице Authorities.

см. документацию гибернации по индексированным коллекциям

попробуйте удалить аннотацию.

Также как мысль; Вы рассматривали возможность использования набора для сопоставления? это не является строго необходимым, это просто более распространенная форма отображения, вот и все.

2 голосов
/ 26 мая 2009

Я могу порекомендовать вам проверить ваши данные. Если у вас есть пропущенные индексы (в вашем случае столбец идентификатора), то вместо пропущенного идентификатора вы получите нулевое значение в вашем массиве. * 1001 Т.е. *

table authorities:
username id
bob 1
bob 3
bob 5

В результате у вас будет массив: {0 = ноль, 1 = боб, 2 = ноль, 3 = боб, 4 = ноль, 5 = боб}

UPDATE: Я встречал ситуацию в двух случаях:

  1. Пропущенные значения ключа в индексированном столбце id в полномочиях таблица (например, 0,1,3,4,5 - пропущенное значение 2. Hibernate автоматически добавится в значение массива с ключ 2 и значение ноль).
  2. Индексируемые значения расположены по порядку, но выбирают критерии, фильтруют часть из них (например, ваш HQL похож на «от пользователя u join u.authorities a, где a.id = 2». В этом случае гибернация загружает пользователя, но В массиве полномочий у вас будет только 3 значения: 0 - ноль, 1 - ноль, 2 - авторитет с идентификатором 2).
...