Почему у моего дочернего объекта есть нуль во внешнем / первичном ключе? - PullRequest
0 голосов
/ 19 сентября 2019

Я чувствую, что на это отвечают 100 раз.но по какой-то причине я попробовал каждый ответ, и ни один из них не решил мою проблему.

У меня есть простой родитель с простым первичным ключом.У него есть список детей.Внешний ключ является частью составного первичного ключа ребенка.БД - postgresql.

Родительский класс

@Entity
@Table(name = "person")
class Person {
  @Id
  @GeneratedValue(generator = "person_id_seq")
  @Column(name = "person_id")
  private Long personId;

  @OneToMany(mappedBy="person", cascade = CascadeType.ALL)
  private List<PersonIdentifier> personIdentifiers = new ArrayList<>();

  public void addPersonIdentifier(PersonIdentifier pi) {
    this.personIdentifiers.add(pi);
    pi.setPerson(this);
  }

  // other columns and getters / setters left out for brevity
}

Дочерний класс с классом ПК

@Entity
@Table(name = "person_identifier")
@IdClass(PersonIdentifierPK.class)
public class PersonIdentifier {
  @Id
  @Column(name="person_id")
  private Long personId;

  @Id
  @Column(name="person_identifier")
  private String personIdentifier;

  @Id
  @Column(name="person_identifier_type")
  private String personIdentifierType;

  @ManyToOne(fetch=FetchType.LAZY)
  @JoinColumn(name="person_id", insertable=false, updatable=false)
  private Person person;

  // other columns and getters / setters left out for brevity
}

public class PersonIdentifierPK {
  @Column(name = "person_id")
  private Long personId;

  @Column(name = "person_identifier")
  private String personIdentifier;

  @Column(name = "person_identifier_type")
  private String personIdentifierType;

  // getters/setters left out
  @Override
  public int hashCode() {
    // implementation
  }  

  @Override
  public boolean equals(Object obj) {
    // implementation
  }
}

ИСПОЛЬЗОВАНИЕ:

Patient p = new Patient();
PersonIdentifier pi = new PersonIdentifier();
pi.setPersonIdentifierType("NAME");
pi.setPersonIdentifier("John Doe");
p.addPersonIdentifier(pi);
personRepository.save(p);

TransactionManager

public static <T> T getRepository(Class<T> repositoryInterface, Project project) {
    if (entityManager == null) {
        DataSource ds = ConnectionPools.getStagingDB();
        emFactory = entityManagerFactory(ds, hibernateProperties(project.getStagingDbJdbcUrl(), project.getStagingDbUserName(), project.getStagingDbPassword()));
        EntityManagerCreator creator = new EntityManagerCreator();
        entityManager = creator.create(emFactory);
    }

    final JpaTransactionManager xactManager = new JpaTransactionManager(emFactory);
    JpaRepositoryFactory factory = new JpaRepositoryFactory(entityManager);
    factory.addRepositoryProxyPostProcessor(new RepositoryProxyPostProcessor() {
        @Override
        public void postProcess(ProxyFactory factory, RepositoryInformation info) {
            factory.addAdvice(new TransactionInterceptor(xactManager, new MatchAlwaysTransactionAttributeSource()));
        }
    });
    return factory.getRepository(repositoryInterface);
}

, если я удалю cascade=CascadeType.ALL, тогда я получу нового человека в моем лицебаза данных с правильно сгенерированным идентификатором, но таблица person_identifier по-прежнему пуста, очевидно.

однако при каскадном преобразовании не удается что-либо зафиксировать из-за того, что столбец personIdentifier person_id пытается установить значение null.

Насколько я понимаю, с помощью сопоставления, столбца соединения и установки родительского элемента на дочернем элементе этот столбец будет автоматически установлен в том виде, в котором он находится на родительском элементе?

вывод Spring sql выглядиткак это (в родительской таблице есть больше столбцов, я просто удалил их по соображениям конфиденциальности) :

select nextval ('person_id_seq')
insert into person (person_id) values (?)
binding parameter [1] as [BIGINT] - [70]

insert into person_identifier (active, create_date, modified_date, person_id, person_identifier, person_identifier_type) values (?, ?, ?, ?, ?, ?)
binding parameter [1] as [BOOLEAN] - [true]
binding parameter [2] as [TIMESTAMP] - [Thu Sep 19 12:34:52 EDT 2019]
binding parameter [3] as [TIMESTAMP] - [null]
binding parameter [4] as [BIGINT] - [null]
binding parameter [5] as [VARCHAR] - [John Doe]
binding parameter [6] as [VARCHAR] - [NAME]

вы можете видеть, где он передал значение null в person_id вставки person_identifier, даже если онпрошло 70 человек в таблицеs оператор вставки.

это, очевидно, приводит к

ERROR: null value in column "person_id" violates not-null constraint

Я пытался рефакторинг кода множеством способов.Используя встроенный идентификатор, удаляя mappedBy и вместо этого используя joincolumn для родителя.и т. д.

...