Отношение @ManyToOne с таблицей соединения (nullable = false)

Попытка создать отношение @ManyToOne в отдельной таблице между TestEntity и TestAttr, получаем ответ об ошибке:

org.hibernate.PropertyValueException: not-null property references a null or transient value : com.test.TestEntity.testAttr; nested exception is javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value : com.test.TestEntity.testAttr

вот сущность, у которой возникла проблема:

@Table(name = "test_table")
public class TestEntity{

  @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
  @JoinTable(name = "test_attr_test_entity", joinColumns = {@JoinColumn(name = "test_entity_id", nullable = false, updatable = false)},
      inverseJoinColumns = {@JoinColumn(name = "test_attr_id", nullable = false, updatable = false)})
  private TestAttr testAttr;
  .
  .
  .
 }

А при переходе на @ManyToMany работает без ошибок.

Код стойкости:

testEntityRepository.save(testEntity)

Возможно, вы пытаетесь сохранить TestEntity, свойство testAttr которого равно null, но для уверенности нам действительно нужен минимальный воспроизводимый пример. Кроме того, почему вы используете таблицу соединений для отношений «многие к одному»? Это допустимый, но редко бывает хорошей формой.

John Bollinger 04.09.2018 15:48

На самом деле да, я пытаюсь сохранить TestEntity, у которого нет testAttr, а отношение @ManyToOne должно быть необязательным по умолчанию. Так почему я не могу сохранить TestEntity с нулевым testAttr?

Mohamed Ahmed Taher Mohamed 04.09.2018 15:55

не могли бы вы добавить код сущностей?

Ennar.ch 04.09.2018 15:57

1. Почему вы хотите создать таблицу соединений для отношений @ManyToOne. 2. Если вы действительно хотите создать его, вы не можете сохранить TestEntity с нулевым testAttr, потому что вы указали его в name = "test_attr_id", nullable = false,...3. Может быть, просто запишите, чего вы хотите достичь, чтобы мы переосмыслили и предложили какое-то решение.

J.Kennsy 04.09.2018 16:12

1. Мне нужна другая таблица, потому что в большинстве случаев не будет testAttr, и мне не нужен столбец с в основном нулями, 2. Я просто хочу убедиться, что в таблице "test_attr_test_entity" нули недопустимы. .

Mohamed Ahmed Taher Mohamed 04.09.2018 16:34

@ J.Kennsy, почему (name = "test_attr_id", nullable = false, ...) подразумевает, что testAttr не должен быть нулевым, насколько я понимаю, это означает, что столбец "test_attr_id" не должен быть нулевым в таблице "test_attr_test_entity ". Вы можете объяснить?

Mohamed Ahmed Taher Mohamed 05.09.2018 11:26
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
6
680
1

Ответы 1

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


TestEntity

@Entity
public class TestEntity {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    private TestAttr testAttr;
...

TestAttr

@Entity
public class TestAttr {

    @Id
    @GeneratedValue
    private Long id;
...

Пример сохранения с использованием репозиториев Spring Data:

TestAttr attr = new TestAttr();

testAttrRepository.save(attr);

TestEntity entity1 = new TestEntity();
TestEntity entity2 = new TestEntity();

entity1.setTestAttr(attr);
entity2.setTestAttr(attr);

testEntityRepository.save(entity1);
testEntityRepository.save(entity2);

Таблицы

Как вы можете видеть, теперь у TestEntity есть идентификатор testAttr в базе данных:

tables in database

Примечание Это одностороннее отношение OneToMany. (TestEntity ссылается на свой testAttr, но у TestAttr нет списка его testEntities

Поведение методов репо вы можете модерировать с помощью каскадных типов по своему усмотрению. Надеюсь, я помог :)

На самом деле мне нужно иметь отношение в отдельной таблице. И я не знаю, почему (name = "test_attr_id", nullable = false, ...) в этом контексте мешает мне сохранять сущность типа TestEntity без testAttr.

Mohamed Ahmed Taher Mohamed 05.09.2018 10:21

@MohamedAhmedTaherMohamed Если у вас есть отдельная таблица для этого отношения и вы сохраняете TestEntity с помощью testAttr, он создаст строку в этой таблице с идентификатором testEntity и идентификатором testAttr. Если вы не хотите, чтобы в этой таблице были нули, вы не можете сохранять одну сущность без другой.

J.Kennsy 05.09.2018 13:10

Другие вопросы по теме