Будьте в спящем режиме не позволяет внедренному объекту с международным полем быть пустым?

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

@Entity
public class Thing {

    @Id
    public String id;

    public Part part;

}

где Часть является встраиваемым классом, который похож на это

@Embeddable
public class Part {

    public String a;    

    public int b;

}

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

Thing th = new Thing();
th.id = "thing.1";
th.part = null;
session.saveOrUpdate(th);

причины В спящем режиме для выдачи этого Исключения

org.hibernate.PropertyValueException: not-null property references a null or transient value: com.ace.moab.api.jobs.Thing.part

Мое предположение - то, что это происходит, потому что Часть является встроенным классом и так Part.a, и Part.b являются просто столбцами в Вещи таблица базы данных. Так как Thing.part является пустым, в спящем режиме, хочет установить в NULL Part.a и значения столбцов Part.b для строки для вещи 1. Однако Part.b является целым числом, и Будьте в спящем режиме, не позволит целочисленным столбцам в базе данных быть пустыми. Это - то, что вызывает Исключение, правильно?

Таким образом, я ищу обходные решения для этой проблемы. Я заметил создание Part.b, Целое число вместо интервала, кажется, работает, но по причинам я не буду переносить Вас с этим, не хороший вариант для нас.Спасибо!

11
задан Bozho 19 November 2010 в 17:11
поделиться

3 ответа

Я нашел еще один обходной путь и решил им поделиться. Оказывается, если сделать столбец int nullable, то Hibernate не будет выбрасывать PropertyValueException.

@Column(nullable = true)
public Integer b;

Это работает для нас, потому что наше приложение с поддержкой hibernate - единственное, что касалось базы данных, и поэтому мы можем гарантировать, что b будет null только тогда, когда часть будет null. Хотя предложение о нулевой части и использование типа-обертки Integer - отличные предложения, по многим причинам, которые я не могу контролировать, установка столбца в nullable работает лучше для нас. Тем не менее, спасибо, и я надеюсь, что это поможет кому-нибудь еще.

7
ответ дан 3 December 2019 в 09:19
поделиться

Довольно неудобно, да. Вы можете установить значение по умолчанию в поле часть:

private Part part = new Part();

или даже

private Part part = Part.NULL_PART;

(см. Null object patern)

Имейте в виду, что если ваш @Embeddable класс не содержит примитива (который имеет значение по умолчанию), и вы сохраните объект со всеми nullами, вся структура будет сохранена в БД как null, потому что у hibernate нет способа сделать различие в БД, нет ли у вас объекта, или у вас пустой объект. Чтобы обойти эту проблему, если она возникнет, вам придется создать фиктивное поле (boolean лучше всего).

3
ответ дан 3 December 2019 в 09:19
поделиться

Вы абсолютно правы насчет того, что происходит. Когда объект встроенного класса имеет значение NULL, Hibernate представляет это, делая все его столбцы в базе данных нулевыми; К сожалению, это означает, что Hibernate не может отличить встраиваемый объект со значением NULL от встраиваемого объекта со всеми значениями NULL.

Насколько мне известно, если вы не можете сделать поле допускающим значение NULL (сделав его Integer , как вы догадались), единственный способ обойти это - создать собственный тип Hibernate. Должно быть выполнимо, но будет больно делать это таким образом. На самом деле, это, вероятно, будет хуже, чем какая бы то ни было причина, по которой вы не можете использовать целое число - так что это вообще за причина?

2
ответ дан 3 December 2019 в 09:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: