2016-05-25 1 views
2

Допустим, мы имеем @OneToMany соотношение для сущностей А и В. Каждый A может иметь множество B.Добавление JPA @OrderColumn впоследствии приводит к нулевой столбец индекса для ошибки сбора

@Entity 
public class A{ 
    @Id 
    private long id; 
    ... 
    @OneToMany(mappedBy="ref") 
    private List<B> items; 
    ... 
} 

@Entity 
public class B{ 
    @Id 
    private long id; 

    @ManyToOne 
    @JoinColumn(name = "A_ID") 
    private A ref; 
} 

Это приложение находится в производстве в течение некоторого времени, и порядок B, сохраненный в db, не был актуальным до сих пор.

Однако теперь требуется точный порядок Bs. Для этого я добавил @OrderColumn, как показано ниже.

@OneToMany 
@OrderColumn(name="B_ORDER") 
private List<B> items; 

Он отлично работает, а таблица B имеет столбец B_ORDER с порядковыми значениями.

Теперь необходимо обновить производственную базу данных. В таблицу B добавлен новый столбец B_ORDER. Однако для существующих строк этот столбец не имеет значения (null). При попытке получить список Bs для уже существующей записи, я получаю следующее исключение:

org.hibernate.HibernateException: null index column for collection 

Это нормально, чтобы иметь список Bs в любом порядке для старых записей. @OrderColumn имеет свойство «nullable», которое по умолчанию истинно. Но это не помогает.

Есть ли способ JPA для этого или мне нужно заполнить эти нулевые значения в db самостоятельно?

Использование JPA 2.1 с Hibernate 4.3.7.

+0

Вы нашли лучшее решение для этого, чем упомянутое. В идеале, он должен заказывать его по id или что-то или давать случайный список сам по себе. – Aditya

+0

Я не мог попробовать решение, данное в ответе ниже, потому что он прибыл через 4 месяца :) (нет жалоб, спасибо много еще). Мы просто заполнили эти нулевые значения специальным SQL-скриптом. Вы пробовали решение ниже? Если да, напишите свой опыт здесь. –

ответ

0

Проблема, которая у вас есть, заключается в том, что провайдер JPA, в вашем случае Hibernate, нуждается в смежном (не разреженном) порядке значений столбца заказа.

Однако при добавлении нового столбца в новую базу данных, значения будут нулевой, если вы не определили значение по умолчанию 0.

Вы могли бы подумать, что добавление значения по умолчанию будет делать трюк , Извините, это не так. Если вы это сделаете, ваша коллекция всегда будет показывать максимум один элемент.

Чтобы решить эту проблему, вы должны добавить каждую коллекцию в последовательную, не разреженную нумерацию.

На практике вы должны изменить ваше лицо, временным, так что вы можете получить доступ к соответствующему полю:

@Entity 
public class B{ 
@Id 
private long id; 

@ManyToOne 
@JoinColumn(name = "A_ID") 
private A ref; 

@Column(name = "B_ORDER") 
private Integer order; 
} 

Теперь вы можете загрузить все элементы. Теперь вам нужно написать временный метод, который загружает все элементы из базы данных по номерам каждого элемента в коллекции, начиная с 0 до длины коллекции минус 1.

Вышеуказанное предложение является одним из способов что я нахожу удобным. Есть много способов решить эту проблему. Вы даже можете сделать это вручную, если у вас будет достаточно времени.

От этого ответа следует учесть, что элементы коллекции необходимо пронумеровать, начиная с 0. В противном случае Hibernate не загрузит элементы в вашу коллекцию. Вам необходимо выполнить описанные ограничения here.

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